如何在Python中使用Pyppeteer作为开发者?
August 8th, 2023

网络是一个庞大而强大的数据库,每天都有大量数据产生。随着大数据和数据科学的兴起,数据变得比以往更有用,用于训练机器学习算法、洞察未来、预测等目的。

手动逐页提取数据是缓慢且耗时的。网页爬取是一个解决方案,能以编程方式从网络中提取数据。通过浏览器自动化,模拟人类动作如点击和滚动,用户可以高效地收集有用的数据,免去手工操作的繁琐。

在Python中,有多种用于网页爬取的工具和库,包括request、BeautifulSoup、Scrapy、MechanicalSoup、lxml和selenium。本文将介绍另一个强大的选择——Pyppeteer,并探索作为Python开发者如何使用它。

什么是Pyppeteer? Pyppeteer是JavaScript(Node)库Puppeteer的Python封装。它类似于Selenium,支持无头模式,但Pyppeteer本地支持仅限于JavaScript和Chromium浏览器。

无头模式指在无图形用户界面(GUI)的背景下运行网络浏览器。适用于网络自动化、自动测试和网络爬取,大大减少了加载时间和计算需求,一切在后台完成。

为什么选择Pyppeteer? 虽然像request和BeautifulSoup这样的工具适用于静态网站,但对于动态或反应式网站,如ReactJS、AngularJS或VueJS,它们无法处理动态生成的内容。

Pyppeteer提供对整个浏览器及其元素的控制,不同于使用HTTP库如request获取页面内容。这提供更大的灵活性和功能。Pyppeteer适用于屏幕截图、表单提交、自动化UI测试、抓取单页应用程序生成预渲染内容(服务器端渲染),以及在更新的Chrome和JavaScript版本中运行测试等。

实现Pyppeteer 现在你了解了Pyppeteer,让我们开始学习在Python中如何实现它。

首先,最好的做法是为开发环境创建独立的虚拟环境,避免干扰现有库。

Install virtualenv (If you don’t have one)

installing | Window

pip install –upgrade virtualenv

installing | Linux | Mac

pip3 install –upgrade virtualenv

create virtual environment | Window | Linux | Mac

virtualenv pyp-env

activating pyp-env | Window

pyp-env\Scripts\activate

activating pyp-env | Linux | Mac

source pyp-env/bin/activate

安装 Pyppeteer是需要安装的主要依赖项。注意,它要求你运行Python 3.6以上,你可以直接使用pip或从Pyppeteer GitHub仓库安装。

Installing using pip | Window

C:> python -m pip install pyppeteer

Installing using pip | Linux | Mac

$ python3 -m pip install pyppeteer

Installing from a GitHub repository | Window

C:> python -m pip install -U git+https://github.com/miyakogi/pyppeteer.git@dev

Installing from a GitHub repository | Linux | Mac

$ python3 -m pip install -U git+https://github.com/miyakogi/pyppeteer.git@dev

请注意:

  1. 当你第一次运行你的脚本时,Pyppeteer可能会延迟一段时间,因为它需要一些时间来下载Chromium浏览器的最新版本。另外,你也可以在运行你的脚本之前用以下命令手动完成安装:

$ pyppeteer-install

  1. M1苹果机在arm64模式下运行Pyppeteer可能有问题,可能需要通过Rosetta运行。

值得一提的是,Pyppeteer默认有异步支持,这意味着它允许你的脚本/应用程序异步处理浏览器自动化和刮擦过程。当涉及到HTTP调用的任务时,这可能是一个性能提升器。

用Pyppeteer抓取截图 接下来,你将学习如何使用Pyppeteer从网站上捕捉屏幕截图,并将其保存为图片。

首先,导入你所需要的库:

import asyncio

from pyppeteer import launch

然后创建一个异步函数来打开一个网站,并捕获一个屏幕截图:

import asyncio

from pyppeteer import launch

async def main():

# launch chromium browser in the background

browser = await launch()

# open a new tab in the browser

page = await browser.newPage()

# add URL to a new page and then open it

await page.goto(“https://www.python.org/”)

# create a screenshot of the page and save it

await page.screenshot({“path”: “python.png”})

# close the browser

await browser.close()

print(“Starting…”)

asyncio.get_event_loop().run_until_complete(main())

print(“Screenshot has been taken”)

最后,运行你的脚本(app.py):

Window

C:> python app.py

……

Starting…

Screenshot has been taken

Linux | Mac

$ python3 app.py

……

Starting…

Screenshot has been taken 当你看到 “屏幕截图已被拍摄 “时,你应该能够在你的当前目录中看到一个名为 “python.png “的新图像。它看起来应该是这样的:

这是一个简单的使用Pyppeteer进行屏幕截图的例子。不过,Pyppeteer也适用于更复杂的动态网站。在下一节中,您将探索第二个例子,学习如何构建一个简单的网络爬虫脚本,从交互式网站中提取主题标题。这正是Pyppeteer的亮点,因为使用其他工具如request或BeautifulSoup几乎不可能完成这个任务。

使用Pyppeteer抓取复杂页面内容 假设您的任务是从Educative.io/edpresso网站的给定主题名称列表中爬取文章创意。页面内容会根据您在搜索框中输入的内容进行交互式渲染。

通过观看下面的GIF,您可以快速构思脚本需要执行的步骤,以有效提取互动式文章的创意。这些步骤可能包括:

找到搜索框。 在搜索框中输入目标主题。 等待主题加载。 提取关于该主题的所有文章标题。 从搜索框中删除主题。 重复步骤2-5,直到迭代完所有必要的主题。 设置 在实现算法之前,请记住,Pyppeteer默认以无头模式启动Chromium浏览器。对于构建复杂脚本,通常最好手动配置为非无头模式,因为这可以减轻盲目调试的负担。

以下是如何将Pyppeteer配置为非无头模式:

launch browser in non-headless mode

browser = await launch({“headless”: False})

It’s also good choice to allow full screen

To enable full screen on the launched browser

Here how you do that

browser = await launch({“headless”: False, “args”: [“–start-maximized”]})

现在我们再来设置一下脚本的各个环节。

1.找到搜索框 打开网站的第一行代码将类似于本文第一个例子中使用的代码。不过在这里,你需要添加一个新的行,用一个CSS选择器来定位搜索框。你的代码将看起来像这样:

import asyncio

from typing import List

from pyppeteer import launch

async def get_article_titles(keywords: List[str]):

# launch browser in headless mode

browser = await launch({“headless”: False, “args”: [“–start-maximized”]})

# create a new page

page = await browser.newPage()

# set page viewport to the largest size

await page.setViewport({“width”: 1600, “height”: 900})

# navigate to the page

await page.goto(“https://www.educative.io/edpresso”)

# locate the search box

entry_box = await page.querySelector(

   “#__next > div.ed-grid > div.ed-grid-main > div > div.flex.flex-row.items-center.justify-around.bg-gray-50.dark\:bg-dark.lg\:py-0.lg\:px-6 > div > div.w-full.p-0.m-0.flex.flex-col.lg\:w-1\/2.lg\:py-0.lg\:px-5 > div.pt-6.px-4.pb-0.lg\:sticky.lg\:p-0 > div > div > div.w-full.dark\:bg-dark.h-12.flex-auto.text-sm.font-normal.rounded-sm.cursor-text.inline-flex.items-center.hover\:bg-alphas-black06.dark\:hover\:bg-gray-A900.border.border-solid.overflow-hidden.focus-within\:ring-1.border-gray-400.dark\:border-gray-900.focus-within\:border-primary.dark\:focus-within\:border-primary-light.focus-within\:ring-primary.dark\:focus-within\:ring-primary-light > input”

)

2.撰写目标主题

Type keyword in search box

await entry_box.type(keyword)

3.等待主题加载

wait for search results to load

await page.waitFor(4000)

4.提取文章的想法

extract the article titles

topics = await page.querySelectorAll(“h2”)

for topic in topics:

title = await topic.getProperty(“textContent”)

# print the article titles

print(await title.jsonValue())

5.从搜索框中删除主题

clear the input box

for _ in range(len(keyword)):

await page.keyboard.press(“Backspace”)

6.重复步骤2-5(对主题进行迭代) for keyword in keywords:

# type keyword in search box

await entry_box.type(keyword)

# wait for search results to load

await page.waitFor(4000)

# extract the article titles

topics = await page.querySelectorAll(“h2”)

# print the article titles

for topic in topics:

    title = await topic.getProperty(“textContent”)

    print(await title.jsonValue())

# clear the input box

for _ in range(len(keyword)):

    await page.keyboard.press(“Backspace”)

完成脚本 现在你已经建立了算法的各个部分,现在是时候把整个脚本放在一起了。你的完整源代码应该是这样的:

import asyncio

from typing import List

from pyppeteer import launch

async def get_article_titles(keywords: List[str]):

launch browser in headless mode

browser = await launch({“headless”: False, “args”: [“–start-maximized”]})

create a new page

page = await browser.newPage()

set page viewport to the largest size

await page.setViewport({“width”: 1600, “height”: 900})

navigate to the page

await page.goto(“https://www.educative.io/edpresso”)

locate the search box

entry_box = await page.querySelector(

   “#__next > div.ed-grid > div.ed-grid-main > div > div.flex.flex-row.items-center.justify-around.bg-gray-50.dark\:bg-dark.lg\:py-0.lg\:px-6 > div > div.w-full.p-0.m-0.flex.flex-col.lg\:w-1\/2.lg\:py-0.lg\:px-5 > div.pt-6.px-4.pb-0.lg\:sticky.lg\:p-0 > div > div > div.w-full.dark\:bg-dark.h-12.flex-auto.text-sm.font-normal.rounded-sm.cursor-text.inline-flex.items-center.hover\:bg-alphas-black06.dark\:hover\:bg-gray-A900.border.border-solid.overflow-hidden.focus-within\:ring-1.border-gray-400.dark\:border-gray-900.focus-within\:border-primary.dark\:focus-within\:border-primary-light.focus-within\:ring-primary.dark\:focus-within\:ring-primary-light > input”

)

for keyword in keywords:

   print(“====================== {} ======================”.format(keyword))

   # type keyword in search box

   await entry_box.type(keyword)

   # wait for search results to load

   await page.waitFor(4000)

   # extract the article titles

   topics = await page.querySelectorAll(“h2”)

   for topic in topics:

       title = await topic.getProperty(“textContent”)

       # print the article titles

       print(await title.jsonValue())

   # clear the input box

   for _ in range(len(keyword)):

       await page.keyboard.press(“Backspace”)

print(“Starting…”)

asyncio.get_event_loop().run_until_complete(

get_article_titles([“python”, “opensource”, “opencv”])

)

print(“Finished extracting articles titles”)

运行脚本 一旦你的脚本被编译完成,就可以看看它是否工作了。像你通常运行Python脚本那样启动该脚本,如图所示:

$ python3 app.py

Starting…

====================== python ======================

What is the contextlib module?

What is the difference between String find() and index() method?

Installing pip3 in Ubuntu

What is a private heap space?

……

====================== opensource ======================

Knative

How to use ASP.NET Core

What is apache Hadoop?

What is OpenJDK?

What is Azure Data Studio?

…..

====================== opencv ======================

What is OpenCV in Python?

Eye Blink detection using OpenCV, Python, and Dlib

How to capture a frame from real-time camera video using OpenCV

Finished extracting articles titles

[文中代码源自Scrapingbee]

当你运行你的脚本时,它会自动启动Chromium浏览器,然后为Educative.io页面打开一个新标签。然后,它将通过上面强调的所有步骤,打印出每个关键词的爬取文章标题。如果你在运行你的脚本时看到与上述输出类似的结果,那么恭喜你,你成功了

总结 在本文中,您已了解了网页爬取,并探索了Pyppeteer构建脚本的能力,可以实现从简单的网站屏幕截图捕捉到动态、互动网页的网络爬取。然而,这只是基础知识。现在您已经掌握了这些基本知识,请花些时间去访问Pyppeteer的官方文档,满足您的好奇心,探索更多高级功能和用法。

本文转载自-

Subscribe to freeproxyreview
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from freeproxyreview

Skeleton

Skeleton

Skeleton