Python 网络爬虫:实际应用与技术

Python 网络爬虫实际应用通过定位单个或多个域的每个 URL,网络爬虫是一种从 Internet 收集数据的强大方法。许多著名的网络爬虫框架和工具都可用于 Python。利用 requests 和 Beautiful Soup,我们将使用 Python 从头开始​​开发一个简单的网络爬虫。

什么是网络爬虫(Web Crawler)?

“网页抓取”(web crawling)和“网络爬虫”(web scraping)是不同但相似的。网络爬虫是网页抓取的一部分;爬虫的逻辑会发现爬虫代码可以处理的 URL。

网络爬虫从要访问的 URL 种子或列表开始。爬虫在 HTML 中为每个 URL 定位链接,根据指定的标准过滤这些连接,然后将新发现的链接添加到队列中。提取所有 HTML 或其指定子集以通过不同的通道进行处理。

网络爬取技术

每个域的最大页面数、深度或执行时间都可以由爬虫预算决定,网络爬虫通常只查看一小部分网站。

大多数知名网站都包含一个 robots.txt 文件,用于指定每个用户代理不允许抓取网站的哪些部分。 sitemap.xml 文件则列出了可以抓取的页面。

网络爬虫的典型用例包括:

  • 搜索引擎(如 Googlebot、Bingbot、Yandex Bot 等)收集 Web 相当大一部分的所有 HTML。该材料已被编入索引,因此可搜索。
  • 除了 HTML,SEO 分析工具还收集响应时间、响应状态和域之间的链接,以发现损坏的页面并收集反向链接。
  • 跟踪价格的工具通过电子商务网站搜索产品​​页面并提取元数据,包括价格。之后,会定期重新检查产品页面。
  • Web 抓取数据由 Common Crawl 保存在可访问的存储库中。例如,从 2020 年 10 月起,该档案馆拥有 27.1 亿个在线页面。

接下来,我们将对比创建 Python 网络爬虫的三种不同方法。首先使用简单的标准库,然后是用于 HTTP 请求和 HTML 解析的第三方库,然后是网络爬虫框架

从头开始制作一个基本的 Python 网络爬虫

我们需要至少一个库来获取 HTML 解析库和从 URL 中提取链接的 HTML,以在 Python 中开发基本的网络爬虫。 Python 包括用于发起 HTTP 请求和解析 HTML 的 urllib 和 HTML.parser 标准库。你可以在 Github 上找到一个完全由标准库创建的 Python 爬虫示例。

开发者可能会发现用于请求和 HTML 解析的默认 Python 库不友好。其他知名库(例如 requests,也称为 Beautiful Soup)提供了更好的开发者体验。

这两个库可以本地安装。

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):

如果 url 不在 self.visited_urls 中并且 url 不在 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 库下载 URL、使用 Beautiful Soup 库收集 URL、连接 URL 以及使用 add url to visit 过滤 URL 的帮助方法。 要访问的 URL 和已访问的 URL 都保存在不同的列表中。 Crawler 可以在你的终端上使用。

Python crawler.py

对于访问的每个 URL,爬虫记录一行。

C:\Users\Faheem Amin\Downloads\sd.PNG

尽管代码非常简单,但在有效抓取整个网站之前,必须解决许多性能和可用性问题。

  1. 爬虫不支持并行,速度很慢。时间戳显示每个 URL 在大约一秒内被抓取。爬虫不会在它发出的每个请求之间进行任何工作;相反,它只是等待请求得到答复。
  2. 下载 URL 逻辑缺少重试机制,URL 队列不是一个合适的队列,当需要下载的 URL 很多时性能很差。
  3. 链接提取算法不支持按域​​过滤 URL 或排除对静态文件的请求,也不通过删除 URL 查询字符串参数来帮助标准化 URL。
  4. 爬虫会忽略 robots.txt 文件并且不提供自身的标识。

结论

我们将使用外部库获取 URL 和解析 HTML 的 Python 爬虫的源代码与借助著名的 Web 爬虫框架创建的爬虫进行了比较。 Python 是一个高效的网络爬虫框架,易于定制。但是,你必须了解可以插入代码的每个位置以及每个组件的设置。