Python + Playwright爬虫


之前系统的学习过selenium爬虫的框架,其实对于绝大多数情况下基本上已经足够用了。但是最近发现了又一款爬虫神器Playwright,为什么说是神器,总的来说有以下特点:

  • 速度快
  • 安装、使用便利
  • 可远程调试
  • 支持有头和无头
  • 支持调用本地浏览器调试
  • 很方便监听网络资源请求
  • 支持同步和异步
  • 支持多种语言、java、python、nodejs、c#等等
  • 支持主流内核的浏览器、chromiun、firfox、webkit
  • 自动录制生成代码

以上是我亲身体会之后自己总结的,可不是去网上扒拉的。废话不多说,让我们一起感受playwright的强大吧!

一、Playwright的安装

其实就是一个python的一个类库而已,所以使用pip install playwright命令安装即可。

二、安装浏览器及其驱动

安装Playwright后,可以使用playwright install命令,会自动安装chromium、firefox、webkit等三款浏览器以及对应的驱动包。当然这个过程比较漫长,因为安装包比较大,后面会讲如何控制本地浏览器爬虫,所以这一步也可以选择跳过。

另外,如果在公司使用代理的情况下,使用以上命令可能无法安装。这种情况下,可以选择使用脚手架npm install playwright --proxy=xxx.xxx.xxx.xx:xx 这种方式去变相的安装浏览器。亲测~安装完了之后, python也是可以直接使用的。

三、Playwright的使用

首先,贴一下官网API的地址:https://playwright.dev/python/docs/intro。
官网已经讲得特别清楚了,而且有很多的实例,这里我就以我遇到的实际问题跟大家进行一个分享。

调用本地浏览器调试

这种方式的好处在于,你完全可以把浏览器放到你的项目下,这样在其他机器上可以很好的兼容,不用你额外去执行命令安装浏览器,修改代码中的路径。

# 指定缓存目录
user_data_dir = "chromium-1005/chrome-win/user data"
# 指定可执行文件路径
executable_path = "chromium-1005/chrome-win/chrome.exe"
browser = playwright.chromium.launch_persistent_context(user_data_dir=user_data_dir,executable_path=executable_path,accept_downloads=True,headless=True, # 控制无头或有头bypass_csp=True,slow_mo=10,args=['--disable-blink-features=AutomationControlled'],# 禁用正在自动化控制提示)
page = browser.new_page()
page.goto("https://www.baidu.com")
page.wait_for_load_state(state="networkidle") # 等待一段时间内再无其它请求,相当于等画面完全加载

控制已打开的浏览器

这种方式主要是因为通过playwright打开的浏览器在执行完任务后会自动关闭,为了减少浏览器的开销,节省时间,可已选择使用命令打开浏览器配合远程调试模式进行处理。

command = "chrome/chrome --remote-debugging-port=9001"
if self.headless:# 以无头模式启动浏览器command = "chrome/chrome --remote-debugging-port=9001 --headless"
subprocess.Popen(command)
print("浏览器已启动!等待进程创建...")
proccess_pid = ""
while True:time.sleep(1)with os.popen(f"netstat -ano | findstr 9001") as r:text = r.read()if len(text) > 0:pid_info = text.split("\n")[0].split(" ")# 获取进程IDproccess_pid = pid_info[len(pid_info) - 1]break
playwright = sync_playwright().start()
browser = playwright.chromium.connect_over_cdp("http://localhost:9001")
page = browser.new_page()
page.goto("https://www.baidu.com")
page.wait_for_load_state(state="networkidle")
# 关闭进程
os.popen(f"taskkill /im {proccess_pid } /F")

这种方式其实已经很好了,但是存在一个问题,当已经有浏览器被开启时,命令打开浏览器会从缓存加载,不会监听到远程端口, 必须要关掉所有的浏览器之后,才能正常进行控制。 这个问题, 如果有谁有好的方法去解决,就是一个非常完美的方案。欢迎大家探讨!

监听网络资源请求

这是一个我认为非常强大的功能,早在学selenium的时候,我曾经探讨过这个问题,使用selenium要实现这个东西,当时各种百度,最终有了处理方案,但始终还不是特别满意。
但是playwright把这一点简化到了极致,让我不禁被为它折服。

def on_response(self, response):if "https://fanyi.baidu.com/v2transapi" in response.url:result = response.json()print(result)user_data_dir = "chromium-1005/chrome-win/user data"
executable_path = "chromium-1005/chrome-win/chrome.exe"
browser = playwright.chromium.launch_persistent_context(user_data_dir=user_data_dir,executable_path=executable_path,accept_downloads=True,headless=True,bypass_csp=True,slow_mo=10,args=['--disable-blink-features=AutomationControlled'],# 设置代理proxy=ProxySettings(server="http://xxx.xxx.xxx.xxx:xxxx"),
)
page = browser.new_page()
# 监听响应事件
page.on("response", self.on_response)
page.goto("https://fanyi.baidu.com/#zh/jp/你好")
page.wait_for_load_state(state="networkidle")


以上是我通过这玩意儿抓取百度翻译的简单代码。但是需要特别注意一点,在需要代理的情况下,使用无头浏览器必须设置代理,像这样proxy=ProxySettings(server="http://xxx.xxx.xxx.xxx:xxxx"),,否则你会看到以下错误:

chromium浏览器:

webkit浏览器

但firefox却没有发现问题,所以你也可以使用火狐浏览器去避免这一问题。

禁止某些资源加载

很多情况下,我们在抓取的时候并不是所有的请求都需要,但是又不得不等待画面加载完成再进行抓取。那么这种时候,我们可以使用router事件过滤我们不需要的请求,比如图片和css样式。

def on_response(self, response):if "https://fanyi.baidu.com/v2transapi" in response.url:result = response.json()print(result)# 取消请求
def cancel_request(self, route, request):route.abort()
user_data_dir = "chromium-1005/chrome-win/user data"
executable_path = "chromium-1005/chrome-win/chrome.exe"
browser = playwright.chromium.launch_persistent_context(user_data_dir=user_data_dir,executable_path=executable_path,accept_downloads=True,headless=True,bypass_csp=True,slow_mo=10,args=['--disable-blink-features=AutomationControlled'],# 设置代理proxy=ProxySettings(server="http://xxx.xxx.xxx.xxx:xxxx"),
)
page = browser.new_page()
# 正则匹配监听图片和css的请求
page.route(re.compile(r"(\.png)|(\.jpg)|(\.css)"), self.cancel_request)
# 监听响应事件
page.on("response", self.on_response)
page.goto("https://fanyi.baidu.com/#zh/jp/你好")
page.wait_for_load_state(state="networkidle")

最终去掉js和图片的画面:

加上禁止资源处理前,需要12s左右,加上后缩短都3s左右,极大的提升了抓取的效率。另外,如果某些js明确不会影响我们要抓取的数据,也可以做进一步的优化。

模拟手机端

很多情况下我们需要模拟手机端的访问,playwright也能轻易做到。

# 定义手机型号, 可以通过浏览器的开发者查看
phone_name="iPhone 12 Pro Max"
playwright = sync_playwright().start()
phone_obj = playwright.devices[phone_name]self.browser = self.playwright.chromium.launch_persistent_context(**phone_obj,user_data_dir=user_dir,executable_path=brows_executable_path,accept_downloads=True,headless=headless,bypass_csp=True,slow_mo=10,args=['--disable-blink-features=AutomationControlled'])
// 支持的手机型号列表
Blackberry PlayBook
Blackberry PlayBook landscape
BlackBerry Z30
BlackBerry Z30 landscape
Galaxy Note 3
Galaxy Note 3 landscape
Galaxy Note II
Galaxy Note II landscape
Galaxy S III
Galaxy S III landscape
Galaxy S5
Galaxy S5 landscape
Galaxy S8
Galaxy S8 landscape
Galaxy S9+
Galaxy S9+ landscape
Galaxy Tab S4
Galaxy Tab S4 landscape
iPad (gen 6)
iPad (gen 6) landscape
iPad (gen 7)
iPad (gen 7) landscape
iPad Mini
iPad Mini landscape
iPad Pro 11
iPad Pro 11 landscape
iPhone 6
iPhone 6 landscape
iPhone 6 Plus
iPhone 6 Plus landscape
iPhone 7
iPhone 7 landscape
iPhone 7 Plus
iPhone 7 Plus landscape
iPhone 8
iPhone 8 landscape
iPhone 8 Plus
iPhone 8 Plus landscape
iPhone SE
iPhone SE landscape
iPhone X
iPhone X landscape
iPhone XR
iPhone XR landscape
iPhone 11
iPhone 11 landscape
iPhone 11 Pro
iPhone 11 Pro landscape
iPhone 11 Pro Max
iPhone 11 Pro Max landscape
iPhone 12
iPhone 12 landscape
iPhone 12 Pro
iPhone 12 Pro landscape
iPhone 12 Pro Max
iPhone 12 Pro Max landscape
iPhone 12 Mini
iPhone 12 Mini landscape
iPhone 13
iPhone 13 landscape
iPhone 13 Pro
iPhone 13 Pro landscape
iPhone 13 Pro Max
iPhone 13 Pro Max landscape
iPhone 13 Mini
iPhone 13 Mini landscape
JioPhone 2
JioPhone 2 landscape
Kindle Fire HDX
Kindle Fire HDX landscape
LG Optimus L70
LG Optimus L70 landscape
Microsoft Lumia 550
Microsoft Lumia 550 landscape
Microsoft Lumia 950
Microsoft Lumia 950 landscape
Nexus 10
Nexus 10 landscape
Nexus 4
Nexus 4 landscape
Nexus 5
Nexus 5 landscape
Nexus 5X
Nexus 5X landscape
Nexus 6
Nexus 6 landscape
Nexus 6P
Nexus 6P landscape
Nexus 7
Nexus 7 landscape
Nokia Lumia 520
Nokia Lumia 520 landscape
Nokia N9
Nokia N9 landscape
Pixel 2
Pixel 2 landscape
Pixel 2 XL
Pixel 2 XL landscape
Pixel 3
Pixel 3 landscape
Pixel 4
Pixel 4 landscape
Pixel 4a (5G)
Pixel 4a (5G) landscape
Pixel 5
Pixel 5 landscape
Moto G4
Moto G4 landscape
Desktop Chrome HiDPI
Desktop Edge HiDPI
Desktop Firefox HiDPI
Desktop Safari
Desktop Chrome
Desktop Edge
Desktop Firefox

等待某个资源请求出现或完成

有时我们只需要等待某一个请求出现或者完成就可以达到我们的目的,这种情况下,没必要等页面完全加载,这时候可以使用以下监听事件:

  • page.expect_request(url_or_predicate, **kwargs) // 期待出现某个请求时
  • page.expect_request_finished(url_or_predicate, **kwargs) // 期待某个请求完了时使用
  • page.expect_response(url_or_predicate, **kwargs) // 期待出现某个响应时使用

这里只举一个例子,更多请参考官方文档,https://playwright.dev/python/docs/api/class-page#page-wait-for-request:

page.goto("https://www.baidu.com")
# 当出现请求地址地址包含www.baidu.com且响应状态为200时等待结束
page.expect_response(lambda response: "www.baidu.com" in response.url and response.status == 200)

以上就是本次探究的一个总结,至于其它的浏览器操作自动化部分,不在这里敖述,网上一搜一大堆。
这里推荐这篇博客:https://blog.csdn.net/zjkpy_5/article/details/122418811。

还有一个自动生成代码,类似于excel的宏录制的功能,这里不做探究,工具只是一个辅助,多动手去发现其中的规律才能巩固你的基础。

好了,愿看到的小伙伴不会迷路。欢迎大家留言探讨!

Playwright + Python爬虫相关推荐

  1. 关于Python爬虫原理和数据抓取1.1

    为什么要做爬虫? 首先请问:都说现在是"大数据时代",那数据从何而来? 企业产生的用户数据:百度指数.阿里指数.TBI腾讯浏览指数.新浪微博指数 数据平台购买数据:数据堂.国云数据 ...

  2. python爬虫之Scrapy框架的post请求和核心组件的工作 流程

    python爬虫之Scrapy框架的post请求和核心组件的工作 流程 一 Scrapy的post请求的实现 在爬虫文件中的爬虫类继承了Spider父类中的start_urls,该方法就可以对star ...

  3. python爬虫抓取信息_python爬虫爬取网上药品信息并且存入数据库

    我最近在学习python爬虫,然后正好碰上数据库课设,我就选了一个连锁药店的,所以就把网上的药品信息爬取了下来. 1,首先分析网页 2,我想要的是评论数比较多的,毕竟好东西大概是买的人多才好.然后你会 ...

  4. python爬虫案例_推荐上百个github上Python爬虫案例

    现在学生都对爬虫感兴趣,这里发现一些好的github开源的代码,分享给各位 1.awesome-spider 该网站提供了近上百个爬虫案例代码,这是ID为facert的一个知乎工程师开源的,star6 ...

  5. Python培训分享:python爬虫可以用来做什么?

    爬虫又被称为网络蜘蛛,它可以抓取我们页面的一些相关数据,近几年Python技术的到来,让我们对爬虫有了一个新的认知,那就是Python爬虫,下面我们就来看看python爬虫可以用来做什么? Pytho ...

  6. 玩转 Python 爬虫,需要先知道这些

    作者 | 叶庭云 来源 | 修炼Python 头图 | 下载于视觉中国 爬虫基本原理 1. URI 和 URL URI 的全称为 Uniform Resource Identifier,即统一资源标志 ...

  7. 买不到口罩怎么办?Python爬虫帮你时刻盯着自动下单!| 原力计划

    作者 | 菜园子哇 编辑 | 唐小引 来源 | CSDN 博客 马上上班了,回来的路上,上班地铁上都是非常急需口罩的. 目前也非常难买到正品.发货快的口罩,许多药店都售完了. 并且,淘宝上一些新店口罩 ...

  8. 一个月入门Python爬虫,轻松爬取大规模数据

    如果你仔细观察,就不难发现,懂爬虫.学习爬虫的人越来越多,一方面,互联网可以获取的数据越来越多,另一方面,像 Python这样一个月入门Python爬虫,轻松爬的编程语言提供越来越多的优秀工具,让爬虫 ...

  9. Python爬虫获取文章的标题及你的博客的阅读量,评论量。所有数据写入本地记事本。最后输出你的总阅读量!

    Python爬虫获取文章的标题及你的博客的阅读量,评论量.所有数据写入本地记事本.最后输出你的总阅读量!还可以进行筛选输出!比如阅读量大于1000,之类的! 完整代码在最后.依据阅读数量进行降序输出! ...

最新文章

  1. 【异常】org.apache.hadoop.hbase.client.RetriesExhaustedException: Failed after attempts=36, exceptions:
  2. 填充因子-FILL FACTOR
  3. 20万数据 sql 快还是 java快?_H2数据库学习(一)
  4. 51CTO 新人报道
  5. python3安装mysqlclient_Python3 安装mysqlclient错误处理(MAC版)
  6. LeetCode之Remove Duplicates from Sorted Array
  7. 百度搜索引擎优化指南3.0_深圳网站搜索引擎排名优化电话,百度优化排名费用_华阳网络...
  8. oracle 插入时if,关于sql:ORACLE:如果不存在则插入行-重复键错误
  9. 初探image-set及如何适配移动端高清屏图片
  10. 全员远程办公,半年入 1 亿美元:GitHub 的最大竞争对手上市了
  11. Arduino温控风扇
  12. 阿里巴巴2015实习面试
  13. 人民日报:今天,大学培养的人才合格吗?
  14. cas:1092775-62-6 ; (ir[dfcf3ppy]2(bpy))pf6热延迟荧光材料TADF
  15. 中创向心力:如何把思想政治教育贯穿职业教育全过程?
  16. C++压缩解压之snappy
  17. 黑鲨可以换鸿蒙系统吗,黑鲨游戏手机系统更新:新增人脸识别等功能
  18. 北大清华联手开设通用人工智能实验班,「顶级AI科学家」朱松纯领衔
  19. 二叉树 左视图 /右视图 [Java实现]
  20. 路由器的工作原理(计算机网络-网络层)

热门文章

  1. 重庆师范大学计算机技术排名,2017年重庆师范大学专业排名
  2. 深入浅出英语语法 -- 动词时态
  3. 鹅厂前员工稍微谈谈腾讯
  4. 软件测试精品书单推荐指南!
  5. java代码编写的文本特征提取_文本特征词提取算法
  6. lopa分析_什么是LOPA分析?
  7. 密评|商用密码应用安全性评估
  8. Visual Studio界面颜色更换 及 Visual Assist X助手使用
  9. Linux系统中的权限详解
  10. 【诗词】曹雪芹:红豆词