有勇气的牛排博客

Pyppeteer爬虫教程:从入门到精通的全面指南

有勇气的牛排 1285 Python 2024-07-19 21:04:24

Pyppeteer爬虫教程:从入门到精通的全面指南

1 前言

Pyppeteer 是 Google 基于 Node.js 开发的工具,而 Pyppeteer 又是什么呢?它实际上是 Puppeteer 的 Python 版本实现。不过,Pyppeteer 并不是由 Google 开发的,而是一位日本工程师根据 Puppeteer 的功能开发出来的非官方版本。

在 Pyppeteer 中,它实际上在后台使用了 Chromium 浏览器来执行网页渲染操作。这两款浏览器(Chromium 和 Chrome)的内核是一样的,可以认为 Chromium 是开发版,而 Chrome 是正式版。

官方文档:https://miyakogi.github.io/pyppeteer/reference.html

2 环境安装

python3.8.5

pyppeteer==0.2.2 websockets==8.1

python3.10.9

pyppeteer==0.2.6 websockets==10.3

注意:需要支持异步,Python3.5+

3 基本参数

params = { 'headless': False, # 关闭无头浏览器 'dumpio': True, # 防止浏览器卡主 r'userDateDir': './cache-data', # 用户文件地址 'args': [ '--disable-infobars', # 关闭 自动化提示框 '--window-size=1920, 1080', # 窗口大小 '--log-level=30', # 日志保存等级,建议设置越小越好,否则生成的日志占用空间很大 30为 warning级别 '--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', '--no-sandbox', # 关闭 沙盒模式 '--start-maximized', # 窗口 最大化 模式 '--proxy-server=http://127.0.0.1:7890' # 代理 ] }

4 案例

4.1 百度搜索

import asyncio import time from pyppeteer import launch async def main(): url = "https://www.baidu.com/" # 启动一个浏览器 # browser = await launch(headless=False, args=['--disable-infobars', '--window-size=1920, 1080']) browser = await launch(**params) # 创建一个页面 page = await browser.newPage() # 设置页面视图大小 await page.setViewport({'width': 1900, 'height': 1080}) # 跳转到百度 await page.goto(url) # 输入要查询的关键字 (select, 内容) await page.type('#kw', '有勇气的牛排') # 点击提交按钮 click 通过 selector点击指定的元素 await page.click('#su') time.sleep(5) await browser.close() asyncio.get_event_loop().run_until_complete(main())

image.png

4.2 xpath爬虫解析a标签

import asyncio import time from pyppeteer import launch async def main(): url = "https://www.couragesteak.com/article/389" # 启动一个浏览器 browser = await launch(**params) # 创建一个页面 page = await browser.newPage() # 设置页面视图大小 await page.setViewport({'width': 1900, 'height': 1080}) # 跳转到页面 await page.goto(url) # 使用XPath选择指定的a元素 xpath = '/html/body/main/article/center[2]/div/a' await page.waitForXPath(xpath) a_element = await page.xpath(xpath) if a_element: a_element = a_element[0] # 选择第一个匹配的元素 # 提取属性 attributes = await page.evaluate('(element) => {' ' const attrs = {};' ' for (let attr of element.attributes) {' ' attrs[attr.name] = attr.value;' ' }' ' return attrs;' '}', a_element) # 提取文本内容 text_content = await page.evaluate('(element) => element.textContent', a_element) print(attributes, text_content) time.sleep(5) await browser.close() asyncio.get_event_loop().run_until_complete(main())

Xpath提取a标签内容属性

5 常用功能

Pyppeteer 三种解析方式

# CSS选择器 Page.querySelector() # xpath表达式 Page.xpath() # 简写 Page.J(), Page.JJ(), and Page.Jx()

5.1 截屏

原创:有勇气的牛排
参考地址:https://www.couragesteak.com/article/453

# 截屏 await page.screenshot(path='my.png')

5.2 伪装浏览器 绕过检测

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

# 伪装浏览器 绕过检测 await page.evaluateOnNewDocument('() =>{ Object.defineProperties(navigator, { webdriver: { get: () => false } }) }')

验证查看

window.navigator.webdriver

5.3 执行js

# 执行js (这里是es6的箭头函数) my_cookie = await page.evaluate(''' () => { return { cookie: window.document.cookie } } ''') print(my_cookie["cookie"])

5.4 滚动到页面底部

# 滚到到页面底部 await page.evaluate('window.scrollBy(0, document.body.scrollHeight)')

5.6 提取文本

# 提取元素中的文本 element = await page.querySelector(f'.d_time') text = await page.evaluate('(element) => element.textContent', element) print(f"text: {text}")

5.7 批量提取指定元素/id/class的文本

这里以span标签为例

# 等待所有li元素加载 await page.waitForSelector('span') # 提取所有li元素中的文本 li_elements = await page.querySelectorAll('span') li_texts = [await page.evaluate('(element) => element.textContent', li) for li in li_elements] print(li_texts) for i in li_texts: print(i)

5.8 提取超链接属性 a

# 提取所有a元素及其属性 a_elements = await page.querySelectorAll('a') a_attributes = [] for a in a_elements: attributes = await page.evaluate('(element) => {' ' const attrs = {};' ' for (let attr of element.attributes) {' ' attrs[attr.name] = attr.value;' ' }' ' return attrs;' '}', a) a_attributes.append(attributes) print(attributes)

image.png

5.9 XPath 获取属性内容 a标签

# 使用XPath选择指定的a元素 xpath = '/html/body/main/article/center[2]/div/a' await page.waitForXPath(xpath) a_element = await page.xpath(xpath) if a_element: a_element = a_element[0] # 选择第一个匹配的元素 # 提取属性 attributes = await page.evaluate('(element) => {' ' const attrs = {};' ' for (let attr of element.attributes) {' ' attrs[attr.name] = attr.value;' ' }' ' return attrs;' '}', a_element) # 提取文本内容 text_content = await page.evaluate('(element) => element.textContent', a_element) print(attributes, text_content)

image.png

5.10 获取cookie

# 获取Cookie cookies = await page.cookies() print(cookies)

5.11 其他参数

ignoreHTTPSErrors(bool): 是否忽略 HTTPS 错误。默认为 False. headless(bool): 是否以无头模式运行浏览器。默认为 True除非appMode或devtools选项是True。 executablePath(str):要运行的 Chromium 或 Chrome 可执行文件的路径,而不是默认捆绑的 Chromium。 slowMo(int|float):将 pyppeteer 操作减慢指定的毫秒数。 args(List[str]):传递给浏览器进程的附加参数(标志)。 ignoreDefaultArgs(bool): 不要使用 pyppeteer 的默认参数。这是一个危险的选择;小心使用。 handleSIGINT(bool):按 Ctrl+C 关闭浏览器进程。默认为 True. handleSIGTERM(bool):在 SIGTERM 时关闭浏览器进程。默认为True. handleSIGHUP(bool):在 SIGHUP 上关闭浏览器进程。默认为 True. dumpio(bool): 是否将浏览器进程 stdout 和 stderr 通过管道传输到process.stdout和process.stderr。默认为False. userDataDir(str):用户数据目录的路径。 env(dict):指定浏览器可见的环境变量。默认与 python 进程相同。 devtools(bool):是否为每个选项卡自动打开 DevTools 面板。如果有此选项True,则该headless选项将被设置 False。 logLevel(int|str):打印日志的日志级别。默认与根记录器相同。 autoClose(bool):脚本完成后自动关闭浏览器进程。默认为True. loop(asyncio.AbstractEventLoop):事件循环(实验性)。 appMode(bool):已弃用。

6 提取数据

# 调用选析器 await page.waitForXPath('//*[@id="page"]') # 获取 网页 源代码 print(await page.content())
# 在页面内执行 document.querySelector, 如果没有元素匹配指定的选择器,返回值是 None J = querySelector # 在页面内执行 document.querySelector, 然后把匹配到的元素作为第一个参数传给 pageFunction Jeval = querySelectorEval # 在页面执行document.querySelectorAll, 如果没有元素匹配指定选择器,返回值是 [] JJ = querySelectorAll #在页面执行 Array.from(document.querySelectorAll(selector)), 然后把匹配到的元素作为第一个参数传给 pageFunction JJeval = querySelectorEval # XPath 表达式 Jx = xpath

留言

专栏
文章
加入群聊