Python 爬虫——Pyppeteer
Python Spider——Pyppeteer
爬虫具有时效性,该文产生于2023年末
一、爬虫的两种方式
爬虫大致可以分为两类方式:
-
直接请求
直接请求的方式一般是使用python的HTTP请求库发起HTTP请求,然后接收返回的数据再进行解析,这种方式存在很大的局限性。当所爬取的页面是动态加载的页面类型时(Ajax等),往往直接获取的请求数据并不是完整的页面数据,并不能有效的提取需要的数据
-
模拟用户
而模拟用户的方式则可以很好的解决直接请求的难题,顾名思义,就是模拟用户使用浏览器的方式进行页面数据的获取,一般来说获取到的页面数据都是完全渲染之后的结果,可以看到的数据都可以进行内容提取(若页面加载不完全,也可以使用某些方式使得页面完全加载),也是本文章的重点
当然两种方式目前都不是非常完美的解决方案,不同的网站适用于不同的方式,而且也并非百分百成功,成功条件受限于网站的复杂程度,反爬虫严格程度等
二、Pyppeteer
目前python中存在两个主要用于用户模拟的库:
- Selenium
- Pyppeteer
Selenium 是一个用于自动化浏览器操作的工具,常用于模拟用户的真实操作,比如点击、填写表单等。它支持多种浏览器,如 Chrome、Firefox、Safari 等,可以通过驱动程序来控制这些浏览器。不过Selenium在配置的时候往往需要下载对应的浏览器驱动程序,不过在对于多浏览器的支持和泛用性上,会更胜一筹。
Pyppeteer是一个使用Python控制无头和有界面浏览器的库,可用于模拟用户行为、执行JavaScript代码等,适用于网页自动化测试、爬虫和数据挖掘等任务。Pyppeteer相比于Selenium最大的优势是可以实现无头浏览器,它可以在不开启浏览器页面的情况下模拟浏览器进行请求的发送和接收,并且支持原生的Javascript,可以实现更多样化的页面操作
本节将使用Pyppeteer进行Python爬虫的实现
三、爬虫实现
-
首先需要明确需要爬取的页面内容和结构
- 通过分析淘宝搜索之后的页面结构,我们发现该页面较适合使用Pyppeteer进行模拟爬取
-
接下来开始逐步编写爬虫代码(由于淘宝的反爬虫非常厉害,所以该程序具有时效性,请针对实际情况进行适当的修改)
-
首先需要引入pyppeteer模块和asyncio模块
import asyncio from pyppeteer import launch # 设定一个爬取数值,表示需要爬取的条目数量 expItemNum = 60 # 设定淘宝搜索页面的url为起始页面 url = "商品搜索页面URL" # 为了防止反爬虫立刻就发现我们,这里务必要设置用户代理 user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Edg/120.0.0.0" # 创建一个函数,同时设定几个基本参数 async def taobaoSearchItem( expItemNum, url, user_agent, wait_sec=1, headless_=False, width=1366, height=768 ): """ expItemNum: 需要的数据条目数(程序在多少数据量时会停止)\n url: 淘宝商品页面的url(已经搜索后打开页面的网址)\n user_agent: 请求头用户代理\n wait_sec: 等待页面加载的事件(Default: 1),时间粒度为秒\n headless_: 无头模式,(Default: False, 即显示浏览器界面, 无头有BUG)\n width: 浏览器窗口大小(default: 1366)\n height: 浏览器窗口大小(default: 768)\n """ # 用于统计总爬取条目数,判断何时停止爬虫程序 total_num = 0 # 设定一个变量,用于记录爬取页面数量 page_num = 1 # 设定一个列表,列表存放最终爬取的数据,并最后写入文件 data_list = list()
-
然后,我们首先调用launch启动浏览器核心,此时需要有一些参数
async def taobaoSearchItem( expItemNum, url, user_agent, wait_sec=1, headless_=False, width=1366, height=768 ): total_num = 0 page_num = 1 data_list = list() # 通过异步的方式启动浏览器,并返回一个浏览器对象,便于后续的操作 # 其中headless用于规定是否为无头模式,该函数参数中默认为有头模式(无头有Bug) # dumpio 使得当浏览器打开很多页面的时候防止浏览器自身卡顿 # args中有一段字符串参数,参数主要规定了窗口的大小,用户代理信息和启用JS,这样可以保证我们的页面正常加载 browser = await launch( headless=headless_, dumpio=True, args=[ f"--window-size={ width},{ height}, --user-agent={ user_agent}, --enable-javascript" ] ) # 此时等待获取一个浏览器的新页面实例 page = await browser.newPage() # await page.setCookie(cookie) 本来可以通过设置cookie防止反爬虫程序,但是cookie使用时有些问题,直接导致我使用的浏览器被淘宝标记为爬虫程序,导致一直滑块验证 # 这里还可以通过这个方式设定页面的大小,防止页面内容不加载 await page.setViewport({ "width": width, "height": height}) # 这里使用pyppeteer内置的js解释器,在页面中执行js代码,设定浏览器驱动模式,防止反爬虫程序检测到我们的异常状态 await page.evaluate( "() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }" ) # 最后打开页面url,进入淘宝搜索页 await page.goto(url)
-
在完成浏览器新建和页面打开之后,我们进入了淘宝页面,此时我们将对于页面内容进行筛选
我们选用pyquery进行html内容的获取,这个模块其实是JQuery的python封装,通过python的方式使用JQuery,可以高效的获取和操作页面DOM
# 下一段代码会用到一个自定义函数,用户获取页面指定标签的html数据 def re_match(html, s_str, type_str): type_f = f"[{ type_str}]" return pq(html)(type_f).filter(lambda i, elem
-