Python网络爬虫 - Phantomjs, selenium/Chromedirver使用

json模块

   什么是json?

      javascript中的对象和数组

      对象 :{key:value}  取值:对象名.key

      数组 :[...,...] 取值:数组[索引值]

    作用

      json格式的字符串 和 Python数据类型 之间的转换

    常用方法

      json.loads() : json格式 --> Python数据类型

        json      python

      对象      字典

      数组      列表

import json

# json格式的数组
jsarray = '[1,2,3,4]'
# 数组 -> 列表
L = json.loads(jsarray)
print(type(L),L)

# json格式对象
jsobj = '{"city":"天地会","name":"步惊云"}'
# 对象 -> 字典
D = json.loads(jsobj)
print(type(D),D)
 

    json.dumps() : Python数据类型 --> json格式

        python       json

      字典         对象

      列表         数组

      元组         数组

L = [1,2,3,4]
T = (1,2,3,4)
D = {"city":"天地会","name":"聂风"}
# python格式 -> json格式
jsarray1 = json.dumps(L)
print(type(jsarray1),jsarray1)

jsarray2 = json.dumps(T)
print(type(jsarray2),jsarray2)

jsobj = json.dumps(D,ensure_ascii=False)
print(type(jsobj),jsobj)

      注意

          json.dumps()默认使用ascii编码

        添加参数ensure_ascii=False,禁用ascii编码

动态网站数据抓取 - Ajax

    特点 :滚动鼠标滑轮时加载

豆瓣电影排行榜数据抓取

    抓取目标 :豆瓣电影 - 排行榜 - 剧情 

                  电影名称 、评分

import json
import requests
import csv


def get_movie(typ, number):
    url = "https://movie.douban.com/j/chart/top_list?"
    headers = {"Users-Agent": "Mozilla/5.0"}
    params = {
        "type": typ,
        "interval_id": "100:90",
        "action": "",
        "start": "0",
        "limit": number
    }

    res = requests.get(url, params=params, headers=headers)
    res.encoding = "utf-8"
    # html 为json数组 [{}, {}, {}...]
    html = res.text
    # 数组 -> 列表
    html = json.loads(html)
    # 用for循环遍历每一个电影信息{}
    for film in html:
        L = [film["title"], film["rating"][0]]
        # {"rating":["9.6","50"],...}
        with open("douban.csv", "a", newline="") as f:
            writer = csv.writer(f)
            writer.writerow(L)


dic = {
    "剧情": "11",
    "喜剧": "24",
    "动作": "5",
    "爱情": "13",
    "动画": "25",
    "惊悚": "19",
    "科幻": "17",
}
cmd = input("请输入电影类型:")
try:
    cmd = cmd.strip()
    get_movie(dic[cmd], input("请输入数量:"))
except KeyError:
    print("类型不存在")
else:
    print("爬取成功呢")

selenium + phantomjs 强大的网络爬虫组合

    selenium

    定义 :Web自动化测试工具,应用于Web自动化测试

    特点

      可以运行在浏览器,根据指定命令操作浏览器,让浏览器自动加载页面

      只是工具,不支持浏览器功能,需要与第三方浏览器结合使用

    phantomjs

      定义 :无界面浏览器(无头浏览器)

      特点

        把网站加载到内存进行页面加载

        运行高效

      安装

      Windows

        将下载的可执行文件放到Python安装目录的Scripts目录下

  C:\Python36\Scripts

      Ubuntu

        将下载的phantomjs放到一个路径下

添加环境变量:

  vi .bashrc 添加

  export PHANTOM_JS=/home/.../phantomjs-2.1.1-...

  export PATH=$PHANTOM_JS/bin:$PATH

  终端:source .bashrc

  终端:phantomjs

# 导入selenium库中的webdriver接口
from selenium import webdriver

# 创建phantomjs浏览器对象
driver = webdriver.PhantomJS()
# 发请求 get()
driver.get("http://www.baidu.com/")
print(driver.page_source)
## 获取网页截屏
driver.save_screenshot("百度.png")
print("图片保存成功")
## 关闭
driver.quit()



from selenium import webdriver
import time

# 创建浏览器对象
driver = webdriver.PhantomJS()
# 打开页面
driver.get("http://www.baidu.com/")
# 发送文字到搜索框
kw = driver.find_element_by_id("kw")
kw.send_keys("美女")
# 点击 "百度一下"
su = driver.find_element_by_id("su")
su.click()
time.sleep(1)
# 获取截屏
driver.save_screenshot("美女.png")
# 关闭浏览器
driver.quit()

  常用方法

    driver.get(url)

    driver.page_source : 获取响应的html源码

    driver.page_source.find("字符串")

      作用 :从html源码中搜索指定字符串

         -1 :查找失败

 非-1   :查找成功

driver = webdriver.PhantomJS()
driver.get("http://www.baidu.com/")
r = driver.page_source.find("ABCDEFG")

  单元素查找

      1、driver.find_element_by_id("").text

      2、driver.find_element_by_class_name("")

      3、driver.find_element_by_xpath('xpath表达式')

      4、如果匹配到多个节点,则只返回第1个节点对象

      多元素查找

        driver.find_elements_by_....

        注意

          如果结果1个,则返回节点对象,不是列表

如果结果N个,则返回列表

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.qiushibaike.com/")

# 查找单个节点 element
r_One = driver.find_element_by_class_name("content")
print(r_One.text)

# 查找多个节点 elements
r_Many = driver.find_elements_by_class_name("content")
for r in r_Many:
    print(r.text)
    print()

driver.quit()

      对象名.send_keys("内容")

      对象名.click()

    案例1 :登录豆瓣网站

from selenium import webdriver
import time

# 创建浏览器对象,发请求
driver = webdriver.Chrome()
driver.get("https://www.douban.com/")
time.sleep(0.5)
# 获取截图(验证码)
driver.save_screenshot("验证码.png")
# 找 用户名、密码、验证、登陆豆瓣按钮
uname = driver.find_element_by_name("form_email")
uname.send_keys("账号")
# 密码
pwd = driver.find_element_by_name("form_password")
pwd.send_keys("密码")
# 验证码
key = input("请输入验证码:")
yzm = driver.find_element_by_id("captcha_field")
yzm.send_keys(key)
driver.save_screenshot("完成.png")
# 点击登陆按钮
login = driver.find_element_by_class_name("bn-submit")
login.click()
time.sleep(1)
driver.save_screenshot("登陆成功.png")
# 关闭浏览器
driver.quit()

  操作键盘

      导模块

      from selenium.webdrier.common.keys import Keys

      常用方法

from selenium import webdriver
# 操作键盘
from selenium.webdriver.common.keys import Keys
import time

# 创建浏览器对象,发请求
driver = webdriver.Chrome()
driver.get("http://www.baidu.com/")
# 百度搜索框输入python
kw = driver.find_element_by_id("kw")
kw.send_keys("python")
driver.save_screenshot("01_python.png")

# 全选 :Ctrl + a
kw = driver.find_element_by_id("kw")
kw.send_keys(Keys.CONTROL,'a')
driver.save_screenshot("02_CtrlA.png")

# 剪切 :Ctrl + x
kw = driver.find_element_by_id("kw")
kw.send_keys(Keys.CONTROL,'x')
driver.save_screenshot("03_CtrlX.png")

# 粘贴 :Ctrl + v
kw = driver.find_element_by_id("kw")
kw.send_keys(Keys.CONTROL,'v')
driver.save_screenshot("04_CtrlV.png")

# 清空搜索框 : 对象名.clear()
kw = driver.find_element_by_id("kw")
kw.clear()
driver.save_screenshot("05_Clear.png")

# 输入 :达内科技
kw = driver.find_element_by_id("kw")
kw.send_keys("达内科技")
driver.save_screenshot("06_Tarena.png")

# 输入 :回车
kw = driver.find_element_by_id("kw")
kw.send_keys(Keys.ENTER)
time.sleep(1)
driver.save_screenshot("07_Enter.png")

# 关闭浏览器
driver.quit()

斗鱼直播网站主播信息抓取(JS分页加载)

      抓取目标 :主播名称 、观众人数

        主播 :class -> dy-name ellipsis fl

        //div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"]

        人数 :class -> dy-num fr

        //div[@id="live-list-content"]//span[@class="dy-num fr"]

      下一页按钮(能点) :class -> shark-pager-next

      下一页按钮(不能点)

        class -> shark-pager-next shark-pager-disable shark-pager-disable-next

from selenium import webdriver
from lxml import etree
import time

# 把Chrome设置无界面浏览器
opt = webdriver.ChromeOptions()
opt.set_headless()
# 创建浏览器对象,发请求
driver = webdriver.Chrome(options=opt)
driver.get("https://www.douyu.com/directory/all")
i = 1

# 循环
while True:
    # 解析(driver.page_source)
    # 获取主播名称 和 观众人数
    parseHtml = etree.HTML(driver.page_source)
    names = parseHtml.xpath('//div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"]')
    numbers = parseHtml.xpath('//div[@id="live-list-content"]//span[@class="dy-num fr"]')
    
    for name,number in zip(names,numbers):
        print("\t主播名称:%s \t观众人数:%s" %
              (name.text.strip(),number.text.strip()))
        #for name,number in [("主播1","20万"),("主播2","15万")]
    print("第%d页爬取成功" % i)
    i += 1
    # 判断是否需要点击下一页
    # 能点 :点击,继续循环
    if driver.page_source.find("shark-pager-disable-next") == -1:
        driver.find_element_by_class_name("shark-pager-next").click()
        time.sleep(1)
    else:
        break
    # 不能点 :break

print("一共爬取了%d页" % i)

  Chromdriver如何设置无界面模式

    1、opt = webdriver.ChromeOptions()
    2、opt.set_headless()
    3、driver = webdriver.Chrome(options=opt)
    4、driver.get(url)


 

京东商品爬取

    1、目标

      1、商品名称

      2、商品价格

      3、评论数量

      4、商家名称

from selenium import webdriver
import time
import csv

# 接受用户输入,访问京东
pro = input("请输入要爬取的商品:")
driver = webdriver.Chrome()
driver.get("https://www.jd.com/")
i = 1
# 发送文字到搜索框,点击搜索
text = driver.find_element_by_class_name("text")
text.send_keys(pro)

button = driver.find_element_by_class_name("button")
button.click()
time.sleep(1)

while True:
    # 动态加载-->全部加载
    # 执行脚本,进度条拉到底部
    driver.execute_script(
       'window.scrollTo(0,\
        document.body.scrollHeight)')
    time.sleep(2) 
    # 正常解析爬取
    r_list = driver.find_elements_by_xpath\
          ('//div[@id="J_goodsList"]//li')

    # r为每一个商品的节点对象
    for r in r_list:
        m = r.text.split('\n')
        # ["¥52.80","Python...","200+",]
        price = m[0]
        name = m[1]
        commit = m[2]
        market = m[3]
        
        with open("商品.csv","a",newline="",encoding="gb18030") as f:
            writer = csv.writer(f)
            L = [name.strip(),price.strip(),
                 commit.strip(),market.strip()]
            writer.writerow(L)
    
    print("第%d页爬取成功" % i)
    i += 1
    # 点击下一页

猜你喜欢

转载自blog.csdn.net/u011537073/article/details/86591546