要在 Python/ target=_blank class=infotextkey>Python 中构建一个简单的网络爬虫,我们至少需要一个库来从 URL 下载 html,还需要一个 HTML 解析库来提取链接。Python 提供标准库urllib用于发出 HTTP 请求和html.parser用于解析 HTML。仅使用标准库构建的 Python 爬虫示例可以在Github上找到。
用于请求和 HTML 解析的标准 Python 库对开发人员不太友好。其他流行的库,如requests、品牌为人类的 HTTP 和Beautiful Soup提供了更好的开发者体验。
如果您想了解更多信息,可以查看有关最佳 Python HTTP 客户端的指南。
您可以在本地安装这两个库。
pip install requests bs4
可以按照前面的架构图搭建一个基本的爬虫。
import logging
from urllib.parse
import urljoin
import requests
from bs4
import BeautifulSoup
logging.basicConfig(
format=
'%(asctime)s %(levelname)s:%(message)s',
level=logging.INFO)
class
Crawler:
def
__init__(
self, urls=[]):
self.visited_urls = []
self.urls_to_visit = urls
def
download_url(
self, url):
return requests.get(url).text
def
get_linked_urls(
self, url, html):
soup = BeautifulSoup(html,
'html.parser')
for link
in soup.find_all(
'a'):
path = link.get(
'href')
if path
and path.startswith(
'/'):
path = urljoin(url, path)
yield path
def
add_url_to_visit(
self, url):
if url
not
in self.visited_urls
and url
not
in self.urls_to_visit:
self.urls_to_visit.Append(url)
def
crawl(
self, url):
html = self.download_url(url)
for url
in self.get_linked_urls(url, html):
self.add_url_to_visit(url)
def
run(
self):
while self.urls_to_visit:
url = self.urls_to_visit.pop(
0)
logging.info(
f'Crawling: {url}')
try:
self.crawl(url)
except Exception:
logging.exception(
f'Failed to crawl: {url}')
finally:
self.visited_urls.append(url)
if __name__ ==
'__main__':
Crawler(urls=[
'https://www.imdb.com/']).run()
上面的代码定义了一个 Crawler 类,其中包含使用 requests 库的 download_url、使用 Beautiful Soup 库的 get_linked_urls 和过滤 URL 的 add_url_to_visit 的帮助方法。要访问的 URL 和已访问的 URL 存储在两个单独的列表中。您可以在终端上运行爬虫。
python crawler.py
爬虫为每个访问的 URL 记录一行。
2020-12-04 18:10:10,737 INFO:Crawling: https://www.imdb.com/
2020-12-04 18:10:11,599 INFO:Crawling: https://www.imdb.com/?ref_=nv_home
2020-12-04 18:10:12,868 INFO:Crawling: https://www.imdb.com/calendar/?ref_=nv_mv_cal
2020-12-04 18:10:13,526 INFO:Crawling: https://www.imdb.com/list/ls016522954/?ref_=nv_tvv_dvd
2020-12-04 18:10:19,174 INFO:Crawling: https://www.imdb.com/chart/top/?ref_=nv_mv_250
2020-12-04 18:10:20,624 INFO:Crawling: https://www.imdb.com/chart/moviemeter/?ref_=nv_mv_mpm
2020-12-04 18:10:21,556 INFO:Crawling: https://www.imdb.com/feature/genre/?ref_=nv_ch_gr
代码非常简单,但是在成功爬取一个完整的网站之前,还有许多性能和可用性问题需要解决。