网络爬虫:使用Python高效抓取数据
网络爬虫是一种从网站提取信息并将其用于特定目的的技术。 它的核心思想是从网页中定位和提取所需的数据,例如表格、列表或其他特定元素。 例如,您可能需要从网页中提取表格数据,将其转换为JSON格式,并使用JSON数据构建内部工具。 通过网络爬虫,您可以高效地收集和处理网页数据。
使用Python进行网络爬虫是一个非常受欢迎的选择。 Python 提供了多种功能强大的库,例如BeautifulSoup和Scrapy,这些库可以帮助您有效地提取网页上的数据。 掌握网络爬虫技能对于开发人员和数据科学家来说至关重要。 本文将指导您如何有效地抓取网站,并获取必要的数据进行后续操作。 在本文中,我们将使用BeautifulSoup库,这是一个在Python中流行的网络爬虫库。
为什么选择Python进行网络爬虫?
Python之所以成为许多开发人员构建网络爬虫工具的首选语言,原因有很多。 本文将重点介绍使用Python进行数据抓取的三大主要原因:
强大的库和活跃的社区支持: Python拥有众多出色的库,如BeautifulSoup、Scrapy和Selenium,它们提供了强大的网络爬虫功能。 这些库构建了一个完整的网络爬虫生态系统,同时由于全球大量开发人员都在使用Python,当您遇到问题时,可以迅速获得帮助和支持。
自动化能力: Python以其强大的自动化功能而闻名。 如果您需要构建复杂的、依赖于网络爬虫的工具,那么仅仅进行网页数据提取是不够的。 例如,如果您想开发一个工具来跟踪在线商店商品的价格变化,则需要添加自动化功能,以便它可以定期跟踪价格并将数据存储到数据库中。 Python 可以帮助您轻松实现这些自动化任务。
数据可视化: 网络爬虫在数据科学领域有着广泛的应用。 数据科学家经常需要从网页中提取数据。 借助Pandas等库,Python可以帮助您轻松地将原始数据转换为可视化图表,从而更好地理解数据。
Python网络爬虫的常用库
Python提供了几个用于简化网络爬虫的库。 以下是三个最流行的库:
1. BeautifulSoup
BeautifulSoup是最流行的网络爬虫库之一。 自2004年以来,它一直在帮助开发人员抓取网页。它提供了简单的方法来导航、搜索和修改解析树。 BeautifulSoup还负责处理传入和传出的数据编码。 它维护良好,并拥有一个庞大的活跃社区。
2. Scrapy
Scrapy是另一个流行的网络爬虫框架。 它在GitHub上拥有超过43000颗星。 它还可以用于从API中提取数据。 它还具有一些内置的功能,例如发送电子邮件。
3. Selenium
Selenium主要不是一个网络爬虫库,而是一个浏览器自动化工具。 但是,我们可以很容易地扩展其功能来抓取网页。 它使用WebDriver协议来控制不同的浏览器。 Selenium已经存在了近20年。 使用Selenium,您可以轻松地自动化并从网页中抓取数据。
Python网络爬虫的挑战
在从网站抓取数据的过程中,可能会遇到各种挑战。 这些挑战包括网络缓慢、反爬虫机制、基于IP的阻止以及验证码等问题。这些问题可能会导致数据抓取失败。 但是,您可以通过一些方法有效地绕过这些挑战。 例如,在许多情况下,当在特定的时间间隔内发送的请求超过一定数量时,您的IP地址将被网站屏蔽。 为避免IP阻止,您需要对爬虫进行编码,使其在发送请求后适当暂停一段时间。
开发人员还倾向于在网站上设置蜜罐陷阱。 这些陷阱通常是肉眼不可见的,但是会被爬虫程序检测到。 如果您尝试爬取的网站中设置了这样的陷阱,您需要相应地编写爬虫代码来处理这些陷阱。
验证码是爬虫面临的另一个主要问题。 现在,大多数网站都使用验证码来防止机器人访问其页面。 在这种情况下,您可能需要使用验证码识别工具。
使用Python抓取网站
正如我们前面讨论的,我们将使用BeautifulSoup来抓取网站。 在本教程中,我们将从CoinGecko网站抓取以太坊的历史数据,并将表格数据保存为JSON文件。 接下来,让我们开始构建我们的爬虫程序。
第一步是安装BeautifulSoup和Requests库。 在本教程中,我将使用Pipenv,它是Python的虚拟环境管理器。 您也可以使用Venv,但我个人更喜欢Pipenv。 如何使用Pipenv不在本教程的讨论范围之内。 如果您想了解如何使用Pipenv,请参考相关的指南。 或者,如果您想了解Python虚拟环境,也请查阅相关资料。
通过运行命令pipenv shell
在项目目录中启动Pipenv shell。 这将会在您的虚拟环境中启动一个子shell。 现在,要安装BeautifulSoup,请运行以下命令:
pipenv install beautifulsoup4
同样,对于安装Requests,运行类似的命令:
pipenv install requests
安装完成后,将必要的库导入到主文件中。 创建一个名为main.py
的文件,并导入以下库:
from bs4 import BeautifulSoup import requests import json
下一步是获取历史数据页面的内容,并使用BeautifulSoup中可用的HTML解析器来解析它们。
r = requests.get('https://www.coingecko.com/en/coins/ethereum/historical_data#panel') soup = BeautifulSoup(r.content, 'html.parser')
在上面的代码中,我们使用requests库中的get
方法访问页面。 然后将解析后的内容存储在一个名为soup
的变量中。
现在,开始进行实际的数据抓取部分。 首先,您需要正确地识别DOM中的表格。 如果您打开此页面并使用浏览器中的开发者工具进行检查,您会看到表格的类属性为table table-striped text-sm text-lg-normal
。
CoinGecko以太坊历史数据表格
要正确地定位这个表格,您可以使用find
方法。
table = soup.find('table', attrs={'class': 'table table-striped text-sm text-lg-normal'}) table_data = table.find_all('tr') table_headings = [] for th in table_data[0].find_all('th'): table_headings.append(th.text)
在上面的代码中,我们首先使用soup.find
方法找到表格,然后使用find_all
方法查找表格内的所有tr
元素。 这些tr
元素存储在一个名为table_data
的变量中。 该表格有几个标题元素。 我们初始化一个名为table_headings
的新变量,并将标题保存在列表中。
然后,我们遍历表格的第一行。 在这一行中,我们查找所有的th
元素,并使用text
方法提取它们的文本值,并将这些值添加到table_headings
列表中。 如果您现在打印table_headings
变量,您将看到以下输出:
['Date', 'Market Cap', 'Volume', 'Open', 'Close']
下一步是抓取其余的元素,为每一行生成一个字典,然后将这些字典添加到列表中。
table_details = [] for tr in table_data: th = tr.find_all('th') td = tr.find_all('td') data = {} for i in range(len(td)): if th: # Check if th is not empty data.update({table_headings[0]: th[0].text}) data.update({table_headings[i+1]: td[i].text.replace('n', '')}) if data.__len__() > 0: table_details.append(data)
这是代码的核心部分。 对于table_data
变量中的每个tr
元素,我们首先查找th
元素。 th
元素是表格中显示的日期。 这些th
元素存储在变量th
中。 类似地,所有的td
元素都存储在td
变量中。
我们初始化一个空的字典data
。 然后,我们遍历td
元素的范围。 对于每一行,我们首先用th
的第一个元素更新字典的第一个字段。 代码data.update({table_headings[0]: th[0].text})
将日期和第一个元素的键值对分配给字典。
初始化第一个元素后,我们使用data.update({table_headings[i+1]: td[i].text.replace('n', '')})
来添加其余的数据。 在这里,我们首先使用text
方法提取td
元素的文本,然后使用replace
方法替换所有的’n’。 然后将该值分配给table_headings
列表的第i+1
个元素,因为第i
个元素已经被分配。
然后,如果data
字典的长度大于零,我们将该字典添加到table_details
列表中。 您可以打印table_details
列表进行检查。 但是,我们会将这些值写入一个JSON文件。 让我们看一下代码:
with open('table.json', 'w', encoding='utf-8') as f: json.dump(table_details, f, indent=2, ensure_ascii=False) print('Data saved to json file...')
我们在这里使用json.dump
方法将数据写入名为table.json
的JSON文件。 写入完成后,我们将Data saved to json file...
打印到控制台。
现在,使用以下命令运行该文件:
python main.py
稍后,您将能够在控制台中看到Data saved to JSON file...
文本。 您还会在工作文件目录中看到一个名为table.json
的新文件。 该文件将类似于以下JSON文件:
[ { "Date": "2022-11-27", "Market Cap": "$145,222,050,633", "Volume": "$5,271,100,860", "Open": "$1,205.66", "Close": "N/A" }, { "Date": "2022-11-26", "Market Cap": "$144,810,246,845", "Volume": "$5,823,202,533", "Open": "$1,198.98", "Close": "$1,205.66" }, { "Date": "2022-11-25", "Market Cap": "$145,091,739,838", "Volume": "$6,955,523,718", "Open": "$1,204.21", "Close": "$1,198.98" }, // ... // ... ]
您已经成功地使用Python创建了一个网络爬虫工具。 要查看完整的代码,您可以访问GitHub上的存储库。
结论
本文介绍了如何实现一个简单的Python网络爬虫。 我们讨论了如何使用BeautifulSoup从网站快速抓取数据。 我们还探讨了其他可用的库,以及为什么Python是许多开发人员进行网站抓取的首选语言。
您还可以查看其他网络爬虫框架。