Python 因其强大的库和简单的语法而成为网络搜索的首选。在本文中,我们将探讨网络刮擦的基础知识,并指导您设置 Python 环境,创建第一个网络刮擦程序。我们将向您介绍适用于刮擦任务的关键 Python 库,包括 Beautiful Soup、Playwright 和 lxml。
Python 提供了多个库,使网络搜索变得更容易。下面是一些最常用的库:
HTTP(超文本传输协议)是一种在网络上传输数据的应用层协议。你在浏览器中输入一个 URL,浏览器就会生成一个 HTTP 请求并将其发送给网络服务器。然后,网络服务器将 HTTP 响应发送回浏览器,浏览器再将其渲染为 HTML 页面。对于网页抓取,你需要模仿这一过程,从脚本中生成 HTTP 请求,以编程方式获取网页的 HTTP 内容。
首先,确保您的系统已安装 Python。您可以从 Python 的官方网站下载。
虚拟环境有助于管理依赖关系。使用这些命令创建并激活虚拟环境:
python -m venv scraping_env
source scraping_env/bin/activate
接下来,使用以下命令安装所需的软件包:
pip install requests
pip install beautifulsoup4
pip install lxml
让我们从一个简单的网络抓取器开始,使用请求抓取静态 HTML 内容。
最常见的 HTTP 请求类型是 GET 请求,用于从指定的 URL 获取数据。下面是一个如何向 http://example.com 执行 GET 请求的基本示例。
import requests
url = 'http://example.com'
response = requests.get(url)
请求库提供了几种处理响应的方法:
检查状态代码:确保请求成功。
if response.status_code == 200:
print('Request was successful!')
else:
print('Request failed with status code:', response.status_code)
提取内容:从响应中提取文本或 JSON 内容。
# 以文本形式获取响应内容
page_content = response.text
print(page_content)
# 以 JSON 格式获取响应内容(如果响应是 JSON 格式)
json_content = response.json()
print(json_content)
当资源无法到达、请求超时或服务器返回错误 HTTP 状态(如 404 Not Found、500 Internal Server Error)时,可能会发生 HTTP 和网络错误。我们可以使用请求引发的异常对象来处理这些情况。
import requests
url = 'http://example.com'
try:
response = requests.get(url, timeout=10) # Set a timeout for the request
response.raise_for_status() # Raises an HTTPError for bad responses
except requests.exceptions.HTTPError as http_err:
print(f'HTTP error occurred: {http_err}')
except requests.exceptions.ConnectionError:
print('Failed to connect to the server.')
except requests.exceptions.Timeout:
print('The request timed out.')
except requests.exceptions.RequestException as req_err:
print(f'Request error: {req_err}')
else:
print('Request was successful!')
在网络刮擦中,我们经常需要从 HTML 内容中提取数据。本部分将介绍如何使用一些库(如 Beautiful Soup 或 lxml)从 HTML 元素中定位和提取数据。
HTML(超文本标记语言)是创建网页的标准标记语言。它由嵌套元素组成,用标签表示,如<div>、<p>、<a>等。每个标签都可以有属性,包含文本、其他标签或两者。
XPath 和 CSS 选择器提供了一种多用途方法,可根据 HTML 元素的属性或其在文档中的位置来选择 HTML 元素。
在网络搜刮时,要从网页中提取特定数据,往往需要识别正确的 XPath 或 CSS 选择器来定位 HTML 元素。以下是如何高效查找这些选择器的方法:
大多数现代网络浏览器都内置了开发工具,可以检查网页的 HTML 结构。以下是如何使用这些工具的分步指南:
XPath: /html/body/div/h1
CSS Selector: body > div > h1
Beautiful Soup 是一个用于解析 HTML 和 XML 文档的 Python 库。它提供了简单的方法和属性来浏览和搜索 HTML 结构。
from bs4 import BeautifulSoup
import requests
# 要搜索的网页的 URL
url = 'https://example.com'
# 向 URL 发送 HTTP GET 请求
response = requests.get(url)
# 使用 Beautiful Soup 解析响应的 HTML 内容
soup = BeautifulSoup(response.content, 'html.parser')
# 使用 CSS 选择器查找 <div> 标记内的所有 <h1> 标记
# 作为<body>标记直接子代的所有<h1>标记
h1_tags = soup.select('body > div > h1')
# 遍历找到的 <h1> 标记列表并打印其文本内容
for tag in h1_tags:
print(tag.text)
当 HTML 或 XML 结构与预期不符时,就会出现解析错误,从而导致数据提取问题。可以通过处理 AttributeError 等异常来管理这些错误。
from bs4 import BeautifulSoup
import requests
# 要搜索的网页的 URL
url = 'https://example.com'
# 向 URL 发送 HTTP GET 请求
response = requests.get(url)
try:
# 使用 Beautiful Soup 解析响应的 HTML 内容
soup = BeautifulSoup(response.content, 'html.parser')
# 使用 CSS 选择器查找 <div> 标记内的所有 <h1> 标记
# 作为<body>标记直接子代的所有<h1>标记
h1_tags = soup.select('body > div > h1')
# 遍历找到的 <h1> 标记列表并打印其文本内容
for tag in h1_tags:
print(tag.text)
except AttributeError as attr_err:
# 处理可能出现 AttributeError 的情况(例如,当 response.content 为 None 时)
print(f'Attribute error occurred: {attr_err}')
except Exception as parse_err:
# 处理解析过程中可能出现的任何其他异常
print(f'Error while parsing HTML: {parse_err}')
除了 Beautiful Soup,另一个在 Python 中解析 HTML 和 XML 文档的流行库是 lxml。BeautifulSoup 侧重于为导航和操作解析后的数据提供方便的界面,而 lxml 则以速度和灵活性著称,使其成为对性能要求较高的任务的首选。
from lxml.html import fromstring
import requests
# 要搜索的网页的 URL
url = 'https://example.com'
# 向 URL 发送 HTTP GET 请求
response = requests.get(url)
# 使用 lxml 的 fromstring 方法解析响应的 HTML 内容
parser = fromstring(response.text)
# 使用 XPath 查找第一个<h1>标记的文本内容
# 位于 <div> 标记内,该标记是 <body> 标记的直接子标记
title = parser.xpath('/html/body/div/h1/text()')[0]
# 打印标题
print(title)
与 Beautiful Soup 类似,lxml 也可以通过捕获类似 lxml.etree.XMLSyntaxError 这样的异常,优雅地处理解析错误。
from lxml.html import fromstring
from lxml import etree
import requests
# 要搜索的网页的 URL
url = 'https://example.com'
# 向 URL 发送 HTTP GET 请求
response = requests.get(url)
try:
# 使用 lxml 的 fromstring 方法解析响应的 HTML 内容
parser = fromstring(response.text)
# 使用 XPath 查找第一个<h1>标记的文本内容
# 位于 <div> 标记内,该标记是 <body> 标记的直接子标记
title = parser.xpath('/html/body/div/h1/text()')[0]
# 打印标题
print(title)
except IndexError:
# 处理 XPath 查询不返回任何结果的情况
print('No <h1> tag found in the specified location.')
except etree.XMLSyntaxError as parse_err:
# 在解析过程中处理 XML 语法错误
print(f'Error while parsing HTML: {parse_err}')
except Exception as e:
# 处理任何其他异常
print(f'An unexpected error occurred: {e}')
从 HTML 元素中成功提取数据后,下一步就是保存这些数据。Python 提供了多种保存刮擦数据的选项,包括保存到 CSV 文件、JSON 文件和数据库。下面概述了如何使用不同格式保存提取的数据:
CSV(逗号分隔值)是一种简单而广泛使用的表格数据存储格式。Python 中的 CSV 模块可以轻松地将数据写入 CSV 文件。
import csv
# 样本数据
data = {
'title': 'Example Title',
'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}
# 将数据保存为 CSV 文件
with open('scraped_data.csv', mode='w', newline='', encoding='utf-8') as file:
writer = csv.writer(file)
writer.writerow(['Title', 'Paragraph'])
for paragraph in data['paragraphs']:
writer.writerow([data['title'], paragraph])
print('Data saved to scraped_data.csv')
JSON(JavaScript Object Notation,JavaScript 对象符号)是一种轻量级数据交换格式,易于读写。Python 中的 JSON 模块提供了以 JSON 格式保存数据的方法。
import json
# 样本数据
data = {
'title': 'Example Title',
'paragraphs': ['Paragraph 1', 'Paragraph 2', 'Paragraph 3']
}
# 将数据保存到 JSON 文件
with open('scraped_data.json', mode='w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
print('Data saved to scraped_data.json')
Playwright 是一款功能强大的工具,可用于采集动态内容并与网页元素进行交互。它可以处理静态 HTML 解析器无法处理的 JavaScript 繁重网站。
安装 Playwright 并进行设置:
pip install playwright
playwright install
Playwright 允许你与网络元素进行交互,如填写表格和点击按钮。它可以等待 AJAX 请求完成后再继续操作,因此非常适合于采集动态内容。
所提供的代码使用 Playwright 和 lxml 对亚马逊产品页面执行网络刮擦。首先,导入必要的模块。定义了一个运行函数来封装搜索逻辑。该函数首先会设置一个代理服务器,并通过代理以非无头模式启动一个新的浏览器实例,以便我们观察浏览器的操作。在浏览器上下文中,打开一个新页面并导航到指定的亚马逊产品 URL,超时 60 秒以确保页面完全加载。
然后,脚本与页面交互,通过使用定位器和文本匹配,从下拉菜单和产品选项中选择特定的产品样式。在确保这些交互完成且页面再次完全加载后,就会捕获页面的 HTML 内容。
然后使用 lxml 的 fromstring 方法解析 HTML 内容,创建元素树。使用 XPath 查询从 ID 为 productTitle 的特定元素中提取产品标题的文本内容。该脚本包含错误处理功能,可处理 XPath 查询不返回结果、解析过程中出现 XML 语法错误或其他意外异常的情况。最后,会打印 tlxml 提取的产品标题,并关闭浏览器上下文和浏览器以结束会话。
运行函数在由 sync_playwright 启动的 Playwright 会话中执行,确保整个过程在受控环境中管理和执行。这种结构可确保在执行网络刮擦任务时的稳健性和抗错能力。
from playwright.sync_api import Playwright, sync_playwright
from lxml.html import fromstring, etree
def run(playwright: Playwright) -> None:
# 定义代理服务器
proxy = {"server": "https://IP:PORT", "username": "LOGIN", "password": "PASSWORD"}
# 使用指定代理并以非无头模式启动一个新的浏览器实例
browser = playwright.chromium.launch(
headless=False,
proxy=proxy,
slow_mo=50,
args=['--ignore-certificate-errors'],
)
# 创建新的浏览器上下文
context = browser.new_context(ignore_https_errors=True)
# 在浏览器上下文中打开新页面
page = context.new_page()
# 导航至指定的亚马逊产品页面
page.goto(
"https://www.amazon.com/A315-24P-R7VH-Display-Quad-Core-Processor-Graphics/dp/B0BS4BP8FB/",
timeout=10000,
)
# 等待页面完全加载
page.wait_for_load_state("load")
# 从下拉菜单中选择特定产品样式
page.locator("#dropdown_selected_style_name").click()
# 选择特定产品选项
page.click('//*[@id="native_dropdown_selected_style_name_1"]')
page.wait_for_load_state("load")
# 获取已加载页面的 HTML 内容
html_content = page.content()
try:
# 使用 lxml 的 fromstring 方法解析 HTML 内容
parser = fromstring(html_content)
# 使用 XPath 提取产品标题的文本内容
product_title = parser.xpath('//span[@id="productTitle"]/text()')[0].strip()
# 打印提取的产品标题
print({"Product Title": product_title})
except IndexError:
# 处理 XPath 查询不返回任何结果的情况
print('Product title not found in the specified location.')
except etree.XMLSyntaxError as parse_err:
# 在解析过程中处理 XML 语法错误
print(f'Error while parsing HTML: {parse_err}')
except Exception as e:
# 处理任何其他异常
print(f'An unexpected error occurred: {e}')
# 关闭浏览器上下文和浏览器
context.close()
browser.close()
# 使用 sync_playwright 启动 Playwright 会话并运行脚本
with sync_playwright() as playwright:
run(playwright)
使用 Python 进行网络刮擦是一种从网站上获取数据的强大方法。所讨论的工具有助于提取、处理和存储用于各种目的的网络数据。在这一过程中,使用代理服务器交替 IP 地址和在请求之间实施延迟是规避拦截的关键。Beautiful Soup 对初学者来说非常友好,而 lxml 则因其高效性而适合处理大型数据集。对于更高级的刮擦需求,尤其是动态加载的 JavaScript 网站,Playwright 被证明是非常有效的。
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.com!
评论: 0