Python3+selenium+PyQuery进行页面抓取

       最近几天因业务需求,需进行数据抓取,但是使用node.js抓取时,发现目标网站必须使用viewstatue进行模拟请求,所以使用selenium进行模拟抓取,下面主要记录本次的难点。
       1、selenium的配置及使用

       在开始前必须进行环境配置,先下载selenium对应本机chrome浏览器的版本,可以参照https://www.cnblogs.com/JHblogs/p/7699951.html自行下载。

       selenium元素选择可以参考https://www.cnblogs.com/yoyoketang/p/6123890.html,有版本区别。

      selenium使用的主要代码: 

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import Select

abspath = os.path.abspath(r"chromedriver.exe")
chrome_options = webdriver.ChromeOptions()
#是否使用无页面模式
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
dr = webdriver.Chrome(abspath,chrome_options=chrome_options) 

       先是Python的引用,下面地址设置,我直接和代码放在一起,也可以设置绝对地址。

       使用无页面模式可以加快抓取效率,但是在测试时有页面可以更加直观。

       2、验证码的识别

      因为要模拟登录所以需要用到验证码识别,本次使用公司之前购买验证识别网站进行识别,但是在使用过程中,因为目标网站验证应该存储在用户session中,所以需要在请求时带着cookie进行请求。

import requests
from requests.cookies import RequestsCookieJar

cookies = dr.get_cookies()
cookie_jar = RequestsCookieJar()

for cookie in cookies:
    cookie_jar.set(cookie['name'], cookie['value'], domain="目标网站host")

element = dr.find_element_by_id('imgs')
img_url = element.get_attribute('src')

data = requests.get(img_url,cookies=cookie_jar).content
f = open('11.png', 'wb')
f.write(data)  
f.close()
#验证码识别
codelib = lib.httplib.httphelper()
info = codelib.validatecode(data)
code = dr.find_element_by_id('txtValidateCode')
code.send_keys(info['pic_str'])

        先通过selenium打开目标网站登录页面,获取cookie,通过cookie进行模拟验证码请求,获取验证图片二进制文件,在进行图片识别,最终实现登录。

        3、PyQuery的使用及数据存储

        因为之前开发使用js较多,所以其它获取元素方法使用不习惯,所以使用PyQuery进行页面元素获取。期间遇到PyQuery无法获取页面元素问题,可以参考https://blog.csdn.net/jewely/article/details/83281228,则可以正常解析。

from pyquery import PyQuery as pq

list_all = []
bo = True
flag = 1
while(True):
    print('正在抓取第%s页,已经抓取%s条!'%(flag,len(list_all)))
    doc = pq(dr.page_source,parser="html")
    #头部文件、实际文件
    items_head = doc('.tableList thead tr')
    items_body = doc('.tableList tbody tr')
    row_hd =[]
    if bo:
        for ii in items_head.find('th'):
            row_hd.append(pq(ii).text().strip())
    for item in items_body:
        row = []
        for ii in pq(item).find('td'):
            row.append(pq(ii).text().strip())
        if bo:
            list_all.append(row_hd)
            bo = False
        list_all.append(row)
    #每到20页保存一次
    if flag%20==0 :
        saveexcel(list_all)
    #判断下一页是否存在
    boex = True
    try:
        dr.find_element_by_link_text('下一页')
    except Exception as err:
        boex = False
    if boex:
        flag = flag + 1
        nextbtn =  dr.find_element_by_link_text('下一页')
        nextbtn.click()
    else:
        break

   因为目标网站无法进行页面跳转,所以使用点击下一页的方式进行,直到无法进行点击为止,则说明抓取完成。如果可以跳转页数,则需要进行异常捕获,出现异常时重新进行请求。

你可能感兴趣的:(Python)