简介
网络爬虫是指利用脚本或程序从网站自动收集数据的过程。它用于提取文本、图像及其他类型的数据,这些信息可用于研究、数据分析或市场分析等多种用途。
如今,关于使用 Python 进行网页抓取的解决方案不胜枚举。Selenium 和 Scrapy 是最广泛使用且广受欢迎的库。虽然这些工具非常适合处理复杂的抓取任务,但对于日常使用而言,它们可能会让人感到有些难以驾驭。
这时,Parsel 这款小巧的爬取库便应运而生。这个轻量级且易于学习的库非常适合小型项目,对于刚接触网页爬取的新手来说更是理想之选。它能够解析 HTML,并利用 CSS 和 XPath 选择器提取数据,对于任何希望快速轻松地从网络上收集信息的“数据爱好者”而言,都是绝佳的工具。
请系好安全带,准备好学习如何使用这个库,跟我一起踏上这场自动化数据采集的冒险之旅。让我们开始抓取吧!
Parsel 入门指南
您可以通过以下命令安装 Parsel 库:
pip install parsel
现在让我们直接进入一个示例项目,从这个简单的网站 https://www.scrapethissite.com/pages/simple/ 抓取所有国家/地区数据。
要获取网站的 HTML 内容,你需要发起一个 HTTP GET 请求。
我们将使用 Python 的 “requests” 库来发送 HTTP 请求,因此请确保已通过以下命令安装该库:
pip install requests
现在您可以获取 HTML 内容并将其写入文件:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
with open("out.html", "w", encoding="utf-8") as f:
f.write(response.text)
并查看其结构:
我们的数据存储在类似于这样的结构中:
<div class="col-md-4 country">
<h3 class="country-name">
<i class="flag-icon flag-icon-af"></i>
Afghanistan
</h3>
<div class="country-info">
<strong>Capital:</strong> <span class="country-capital">Kabul</span><br>
<strong>Population:</strong> <span class="country-population">29121286</span><br>
<strong>Area (km<sup>2</sup>):</strong> <span class="country-area">647500.0</span><br>
</div>
</div><!--.col-->
要编写选择器,你需要将原始 HTML 传递给 Parsel:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
raw_html = response.text
parsel_dom = parsel.Selector(text = raw_html)
现在我们可以开始编写选择器了。
使用 CSS 选择器提取文本
你可以使用以下代码输出第一个国家的首都:
parsel_dom = parsel.Selector(text=raw_html)
first_capital = parsel_dom.css(".country-capital::text").get()
print(first_capital)
// Output
Andorra la Vella
parsel_dom.css(".country-capital::text").get() will select the inner text of the first element that has the country-capital class.
你可以使用以下代码打印所有国家名称:
countries_names = filter(lambda line: line.strip() != "", parsel_dom.css(".country-name::text").getall())
for country_name in countries_names:
print(country_name.strip())
// Output
Andorra
United Arab Emirates
Afghanistan
Antigua and Barbuda
Anguilla
. . .
parsel_dom.css(".country-name::text").getall() will select the inner texts of all the elements that have the "country-name" class.
请注意,我们需要对输出结果进行一些清理。这是因为所有带有“.country-name”类的元素内部都嵌套了一个<i>标签。此外,国家名称周围还带有许多尾随空格。
<h3 class="country-name">
<i class="flag-icon flag-icon-ae"></i> //this is picked up as an empty string
United Arab Emirates // this is picked up as “ United Arab Emirates “
</h3>
现在,让我们编写一个脚本,使用 CSS 选择器提取所有数据:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
raw_html = response.text
parsel_dom = parsel.Selector(text=raw_html)
countries = parsel_dom.css(".country")
countries_data = []
for country in countries:
country_name = country.css(".country-name::text").getall()[1].strip()
country_capital = country.css(".country-capital::text").get()
country_population = country.css(".country-population::text").get()
country_area = country.css(".country-area::text").get()
countries_data.append({
"name": country_name,
"capital": country_capital,
"population": country_population,
"area": country_area
})
for country_data in countries_data:
print(country_data)
// Outputs
{'name': 'Andorra', 'capital': 'Andorra la Vella', 'population': '84000', 'area': '468.0'}
{'name': 'United Arab Emirates', 'capital': 'Abu Dhabi', 'population': '4975593', 'area': '82880.0'}
{'name': 'Afghanistan', 'capital': 'Kabul', 'population': '29121286', 'area': '647500.0'}
... 使用 XPath 选择器提取文本
XPath 是一种用于从 XML 文档中选择节点的查询语言。它代表 XML 路径语言(XML Path Language),并使用类似于 URL 的路径表示法来遍历 XML 文档的元素和属性。XPath 表达式可用于选择单个元素、一组元素或元素的特定属性。 XPath 主要应用于 XSLT,但也可用于遍历任何 XML 类语言文档(如 HTML 或 SVG)的文档对象模型(DOM)。
XPath 初看可能令人望而生畏,但一旦掌握了基本概念和语法,入门其实相当简单。我们的 XPath 选择器指南(https://www.webscrapingapi.com/the-ultimate-xpath-cheat-sheet)是一份非常实用的参考资料。
现在让我们尝试一些选择器:
以下是打印第一个大写字母的方法:
parsel_dom = parsel.Selector(text=raw_html)
first_capital = parsel_dom.xpath('//*[@class="country-capital"]/text()').get()
print(first_capital)
// Output
Andorra la Vella
以及所有国家名称:
countries_names = filter(lambda line: line.strip() != "",
parsel_dom.xpath('//*[@class="country-name"]//text()').getall())
for country_name in countries_names:
print(country_name.strip())
// Output
Andorra la Vella
Abu Dhabi
Kabul
St. John's
The Valley
Tirana
...
让我们使用 XPath 选择器重写该脚本:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
raw_html = response.text
parsel_dom = parsel.Selector(text=raw_html)
countries = parsel_dom.xpath('//div[contains(@class,"country")][not(contains(@class,"country-"))]')
countries_data = []
for country in countries:
country_name = country.xpath(".//h3/text()").getall()[1].strip()
country_capital = country.xpath(".//span/text()").getall()[0]
country_population = country.xpath(".//span/text()").getall()[1]
country_area = country.xpath(".//span/text()").getall()[2]
countries_data.append({
"name": country_name,
"capital": country_capital,
"population": country_population,
"area": country_area
})
for country_data in countries_data:
print(country_data)
// Output
{'name': 'Andorra', 'capital': 'Andorra la Vella', 'population': '84000', 'area': '468.0'}
{'name': 'United Arab Emirates', 'capital': 'Abu Dhabi', 'population': '4975593', 'area': '82880.0'}
{'name': 'Afghanistan', 'capital': 'Kabul', 'population': '29121286', 'area': '647500.0'}
...删除元素
删除元素很简单。只需将 drop 函数应用于选择器即可:
selector.css(".my_class").drop()
让我们编写一个脚本,从每个国家/地区中移除“人口”字段,以此演示这一功能:
import parsel
import requests
response = requests.get("https://www.scrapethissite.com/pages/simple/")
raw_html = response.text
parsel_dom = parsel.Selector(text=raw_html)
countries = parsel_dom.css(".country")
for country in countries:
country.css(".country-population").drop()
country.xpath(".//strong")[1].drop()
country.xpath(".//br")[1].drop()
countries_without_population_html = parsel_dom.get()
with open("out.html", "w", encoding="utf-8") as f:
f.write(countries_without_population_html)

导出数据
完成数据抓取后,考虑如何保存数据至关重要。存储此类数据的两种常见格式是 .json 和 .csv。不过,您应根据项目需求选择最合适的格式。
将数据导出为 .json
JSON(JavaScript 对象表示法)是一种轻量级的数据交换格式,既便于人类阅读和编写,也便于机器解析和生成。它常用于在 Web 应用程序与服务器之间,或 Web 应用程序的不同组件之间交换数据。 JSON 与 Python 字典相似,同样用于以键值对的形式存储数据,且可用于存储和访问相同类型的数据,并具有相同的结构。
使用 json 库可将 Python 字典数组导出为 .json 格式:
import json
countries_dictionaries = [
{'name': 'Andorra', 'capital': 'Andorra la Vella', 'population': '84000', 'area': '468.0'},
{'name': 'United Arab Emirates', 'capital': 'Abu Dhabi', 'population': '4975593', 'area': '82880.0'}
]
json_data = json.dumps(countries_dictionaries, indent=4)
with open("data.json", "w") as outfile:
outfile.write(json_data)
// data.json
[
{
"name": "Andorra",
"capital": "Andorra la Vella",
"population": "84000",
"area": "468.0"
},
{
"name": "United Arab Emirates",
"capital": "Abu Dhabi",
"population": "4975593",
"area": "82880.0"
}
]将数据导出为 .csv
CSV 是一种在文本文件中存储数据的简便方式,其中每行代表一个数据行,每个值由逗号分隔。它常用于电子表格或数据库程序中。Python 通过其 csv 模块,对处理 CSV 文件提供了出色的内置支持。CSV 模块最强大的功能之一是 DictWriter 类,它允许您以简单的方式将 Python 字典写入 CSV 文件。 字典的键将作为 CSV 文件中的列标题,而键值对中的值将作为行中的对应数据写入文件。
以下是使用 csv 库将 Python 字典数组导出为 .csv 文件的方法。
countries_dictionaries = [
{"name": "John Smith", "age": 35, "city": "New York"},
{"name": "Jane Doe", "age": 28, "city": "San Francisco"}
]
with open("data.csv", "w") as outfile:
writer = csv.DictWriter(outfile, fieldnames=countries_dictionaries[0].keys())
writer.writeheader()
for row in countries_dictionaries:
writer.writerow(row)
// data.csv
name,age,city
John Smith,35,New York
Jane Doe,28,San Francisco总结
在本文中,我们探讨了 Python 中 Parsel 库的应用。我们看到了使用 Parsel 提供的 CSS 和 XPath 选择器从网页中提取数据是多么简单。总体而言,Parsel 为网络爬虫提供了高效且多功能的解决方案。如果您对自动化数据采集感兴趣,绝对值得一试。
想进一步了解网页抓取吗?欢迎了解我们的产品 WebScrapingAPI,探索如何将您的数据提取技能提升到新高度。我们功能强大的 API 专为帮助您克服网页抓取中最常见的挑战而设计,例如避免 IP 封禁或加载 JavaScript。最棒的是?您可以免费试用!




