Python 网络爬虫
最后修改于 2024 年 1 月 29 日
在本文中,我们将展示如何在 Python 中进行网络抓取。 我们使用多个 Python 库。
网络抓取是从网页中获取和提取数据。 网络抓取用于收集和处理用于营销或研究的数据。 这些数据包括职位列表、价格比较或社交媒体帖子。
Python 是数据科学的常用选择。 它包含许多用于网络抓取的库。 要获取数据,我们可以使用 requests 或 urllib3 库。 如果我们想创建异步客户端,可以使用 httpx 库。
要处理数据,我们可以使用 lxml、pyquery 或 BeautifulSoup。 这些库适用于静态数据。 如果数据隐藏在 JavaScript 之后,我们可以使用 Selenium 或 PlayWright 库。
使用 urllib3 和 lxml 进行网络抓取
在第一个示例中,我们使用 urllib3 获取数据,并使用 lxml 处理数据。
#!/usr/bin/python
import urllib3
from lxml import html
http = urllib3.PoolManager()
url = 'http://webcode.me'
resp = http.request('GET', url)
content = resp.data.decode('utf-8')
root = html.fromstring(content)
print('------------------------')
print(root.head.find(".//title").text)
print('------------------------')
for e in root:
print(e.tag)
print('------------------------')
print(root.body.text_content().strip())
该程序检索 HTML 标题、标签和 HTML 主体的文本内容。
http = urllib3.PoolManager()
创建一个 PoolManager。 它处理连接池和线程安全的所有细节。
url = 'http://webcode.me'
resp = http.request('GET', url)
我们向指定的 URL 生成一个 GET 请求。
content = resp.data.decode('utf-8')
root = html.fromstring(content)
我们获取并解码内容。 我们解析字符串以创建 lxml 的 HTML 文档。
print(root.head.find(".//title").text)
我们打印文档的标题。
for e in root:
print(e.tag)
这里我们打印文档第一层的所有标签。
print(root.body.text_content().strip())
我们打印 HTML 主体的文本数据。
$ ./main.py
------------------------
My html page
------------------------
head
body
------------------------
Today is a beautiful day. We go swimming and fishing.
Hello there. How are you?
使用 requests 和 pyquery 进行网络抓取
在第二个示例中,我们使用 requests 库来获取数据,并使用 pyquery 来处理数据。
#!/usr/bin/python
from pyquery import PyQuery as pq
import requests as req
resp = req.get("http://www.webcode.me")
doc = pq(resp.text)
title = doc('title').text()
print(title)
pars = doc('p').text()
print(pars)
在该示例中,我们从所有 p 标签获取标题和文本数据。
resp = req.get("http://www.webcode.me")
doc = pq(resp.text)
我们生成一个 GET 请求,并从响应中创建一个可解析的文档对象。
title = doc('title').text()
print(title)
我们从文档中获取标题标签并打印其文本。
$ ./main.py My html page Today is a beautiful day. We go swimming and fishing. Hello there. How are you?
Python 抓取字典定义
在下一个示例中,我们从 dictionary.com 抓取单词的定义。 我们使用 requests 和 lxml 库。
#!/usr/bin/python
import requests as req
from lxml import html
import textwrap
term = "dog"
resp = req.get("http://www.dictionary.com/browse/" + term)
root = html.fromstring(resp.content)
for sel in root.xpath("//span[contains(@class, 'one-click-content')]"):
if sel.text:
s = sel.text.strip()
if (len(s) > 3):
print(textwrap.fill(s, width=50))
该程序获取术语 dog 的定义。
import textwrap
textwrap 模块用于将文本包装到特定宽度。
resp = req.get("http://www.dictionary.com/browse/" + term)
要执行搜索,我们将术语附加到 URL 的末尾。
root = html.fromstring(resp.content)
我们需要使用 resp.content 而不是 resp.text,因为 html.fromstring 隐式地期望字节作为输入。 (resp.content 以字节形式返回内容,而 resp.text 以 Unicode 文本形式返回内容。)
for sel in root.xpath("//span[contains(@class, 'one-click-content')]"):
if sel.text:
s = sel.text.strip()
if (len(s) > 3):
print(textwrap.fill(s, width=50))
我们解析内容。 主要定义位于具有 one-click-content 属性的 span 标签内。 我们通过删除多余的空格和杂散字符来改进格式。 文本宽度最大为 50 个字符。 请注意,这种解析可能会发生变化。
$ ./get_term.py a domesticated canid, any carnivore of the dog family Canidae, having prominent canine teeth and, in the wild state, a long and slender muzzle, a deep-chested muscular body, a bushy tail, and large, erect ears. ...
使用 BeautifulSoup 进行 Python 网络抓取
BeautifulSoup 是一个用于解析 HTML 和 XML 文档的 Python 库。 它是最强大的网络抓取解决方案之一。
BeautifulSoup 将复杂的 HTML 文档转换为复杂的 Python 对象树,例如 tag、navigable string 或 comment。
#!/usr/bin/python
from bs4 import BeautifulSoup
import requests as req
resp = req.get('http://webcode.me')
soup = BeautifulSoup(resp.text, 'lxml')
print(soup.title)
print(soup.title.text)
print(soup.title.parent)
在该示例中,我们获取标题标签、标题文本和标题标签的父标签。 为了获取网页,我们使用 requests 库。
soup = BeautifulSoup(resp.text, 'lxml')
创建一个 BeautifulSoup 对象; HTML 数据被传递给构造函数。 第二个选项指定内部解析器。
print(soup.title) print(soup.title.text) print(soup.title.parent)
我们使用内置属性获取数据。
$ ./main.py <title>My html page</title> My html page <head> <meta charset="utf-8"/> <meta content="width=device-width, initial-scale=1.0" name="viewport"/> <link href="format.css" rel="stylesheet"/> <title>My html page</title> </head>
Python 抓取前 5 个国家/地区
在下一个示例中,我们提取人口最多的前 5 个国家/地区。
#!/usr/bin/python
from bs4 import BeautifulSoup
import requests as req
resp = req.get('http://webcode.me/countries.html')
soup = BeautifulSoup(resp.text, 'lxml')
data = soup.select('tbody tr:nth-child(-n+5)')
for row in data:
print(row.text.strip().replace('\n', ' '))
为了提取数据,我们使用 select 方法,该方法执行 CSS 选择操作。
$ ./top_countries.py 1 China 1382050000 2 India 1313210000 3 USA 324666000 4 Indonesia 260581000 5 Brazil 207221000
Python 抓取动态内容
我们可以使用 PlayWright 或 Selenium 抓取动态内容。 在我们的示例中,我们使用 PlayWright 库。
$ pip install --upgrade pip $ pip install playwright $ playwright install
我们安装 PlayWright 和驱动程序。
#!/usr/bin/python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("http://webcode.me/click.html")
page.click('button', button='left')
print(page.query_selector('#output').text_content())
browser.close()
网页上只有一个按钮。 当我们点击按钮时,文本消息会出现在输出 div 标签中。
with sync_playwright() as p:
我们以同步模式工作。
browser = p.chromium.launch()
我们使用 chromium 浏览器。 浏览器是无头的。
page = browser.new_page()
page.goto("http://webcode.me/click.html")
我们导航到该页面。
page.click('button', button='left')
我们点击按钮。
print(page.query_selector('#output').text_content())
我们检索消息。
$ ./main.py Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/109.0.5414.46 Safari/537.36
来源
在本文中,我们展示了如何在 Python 中进行网络抓取。
作者
列出所有 Python 教程。