Питхон 爬虫 入门: 常见 工具 介绍

接着 我 的 上 一篇 文章 《网页 爬虫 完全 指南》 , 这篇 文章 将 涵盖 几乎 所有 的 Питхон 网页 爬 取 取 工具。 我们 从 最基本 的 的 开始 讲起 逐步 逐步 涉及 涉及 到 并且 对 对 它们 的 它们利弊 进行 分析。

当然 , 我们 不能 全面 地 介绍 每个 工具 , 但 这篇 文章 应该 足以 让 你 很好 很好 地 哪些 工具 工具 做 什么 什么 , 使用 使用 使用 使用。

注意: 本文 中 所 涉及 到 的 Питхон 均 指 Питхон3。

本文 要点 :

  • Веб 基础
  • Цкет 创建 一个 соцкет 并且 发送 ХТТП 请求
  • урллиб3 и ЛКСМЛ
  • захтеви & БеаутифулСоуп
  • Сцрапи (爬虫 框架)
  • Селен) 浏览 器 自动化 测试 框架) Цхроме & Цхроме —— без главе
  • 总结

Веб 基础

互联网 其实 是非常 复杂 的—— 我们 通过 浏览 器 浏览 一个 简单 的 网页 时 , 其 背后 其实 涉及 到 许多 许多 技术 和 概念。 我 但, 但 我 会 讲解 你 你 如果 如果 如果 如果 中 中 中爬 取 数据 需要 了解 哪些 最 重要 的 知识。

ХиперТект Трансфер Протоцол (超 文本 传输 协议 , 简称 ХТТП)

ХТТП 采用Ц / С 模型, 在 ХТТП 客户 机 (如 浏览 器 , Питхон 程序, цурл (命令 行 工具) , Захтеви 等等) 创建 一个 连接 并向 ХТТП 服务器 (如 Нгинк , Апацхе 等) 发送 信息 (“(想页 产品 页 ”)。

然后 服务器 返回 一个 响应 (如 ХТМЛ 代码) 并且 关闭 连接。 与 ФТП 这些 有 状态 状态 协议 , ХТТП 的 每个 事务 都是 都是 独立 的 状态 协议 协议 协议

Преузми ХТТП протокол:

GET /product/ HTTP/1.1 Host: example.com Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/web\ p,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch, br Connection: keep-alive User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit\ /537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 

在 这个 请求 行 你, 行 你 信息 信息:

  • Преузми, преузми, преузми /product/ХТТП, преузми ХТТП, преузми и преузми
  • ХТТП 协议 的 版本。 在 本 教程 , 我们 我们 重点 讨论 ХТТП1。
  • 多个 заглавље 字段。

以下 字段 最 重要 的 заглавље 字段:

  • Домаћин:服务器 的 域名。 如果 没有 给出 端口 号 , 默认 80 * . *
  • Кориснички агент:包含 包含 有关 发起 请求 的 客户 端 的 信息 包括, 等 ОС 等 信息。。 比如说 上面 例子 例子 表明, 表明 了 我 我 的 浏览 器 (Цхроме Цхроме 在 , 在 Мац ОС Кс 系统 上 上. Хеадер 字段 很 重要 , 因为 它 要么 用于 统计 (有 多少 访问 访问 我 的 移动 和 桌面 网站)) , 要么 要么 用于 机器人 机器人 的 任何 任何 违规 行为。 因为 这些 报 报 头 , 可以 一种 使用 使用 一种 一种名为 “报 头 欺骗” 的 技术 对其 进行 修改。 这 正是 我们 的 爬虫 程序 要做 的 , 使 他们 看起来 像 一个 一个 的 网页 网页。。。
  • Прихватам :表明 响应 可接受 的 内容 类型。 有 许多 不同 的 内容 类型 和 子тект : тект / плаин , тект / хтмл, имаге / јпег, апплицатион / јсон
  • ** Колачић: ** име1 = вредност1; наме2 = валуе2… 这个 хеадер 字段 包含一组 键值 对。 这些 称为 会话 цоокие , 是 网站 用来 验证 用户 身份 和 在 浏览 器 中 存储 数据 的 工具。 比如说 , 当 你 登录 时 填写 完 账号 密码 密码 提交 提交, 服务器 会 检查 你 输入 的 账号 密码 是否 正确。 如果 无误 它将, 它将 重定向 并且 在 你 的 浏览 器 会话 会话 会话 цоокие , 浏览 器 会 将此 цоокие 连同 会话 的 的 请求 请求 一起 发送 给 服务器。。
  • Реферрер : 的 字段。 请求 实际 УРЛ 的 УРЛ。 网站 通过 此 хеадер 字段 来 判断 用户 的 来源 , 进而 调整 该 用户 的 例如 很多, 很多 新闻 网站 都有 付费 订阅 , 浏览 浏览 浏览 10% , 如果 用户 是 来自 像 Реддит 这样 的 新闻 聚合 器 , 就能 浏览 全部 内容。 网站 使用 реферер 头 字段 来 来 进行 检查 这 一点。 有时 , 我们 不得不 伪造 这个 这个 хеадер 字段 来 获取 我们 想要 提取 的 的。。

当然 хеадер 字段 不仅仅是 这些。 你 可以 在 获取 获取 更多 的 信息。

将 返回 响应 响应 响应 响应:

HTTP/1.1 200 OK Server: nginx/1.4.6 (Ubuntu) Content-Type: text/html; charset=utf-8     ...[HTML CODE] 

在 代码 行 我们 看到 看到 一个 ХТТП 代码200 OK。 这 意味着 我们 的 请求 成功 了。。 很多 很多 很多 很多 ТП ХТТП 代码 , 分为 ТП 类: 2КСКС 用于 成功 , 3КСКС 用于 , , 4КСКС 用于 错误 请求 (最著名 是 404 , 5КСКС 用于 服务器 错误。

如果 你 使用 Веб 浏览 器 发送 ХТТП 请求 , 它将 解析 ХТМЛ 代码 , 获取 所有 资源 资源 (ЈаваСцрипт 、 ЦСС 和 图像 文件) , 并将 结果 呈现 到 主 窗口 中。

在 下一节 中 , 我们 将 看到 使用 Питхон 执行 ХТТП 请求 的 不同 方法 , 并 从 响应 中 提取 我们 我们 想要 的 数据。

Цкет 创建 一个 соцкет 并且 发送 ХТТП 请求

Соцкет (套接字)

在 Питхон 中 执行 ХТТП 请求 的 请求 方法 是 打开 一个 соцкет 并 手动 发送 发送 ХТТП 请求:

import socket HOST = 'www.google.com' # Server hostname or IP address PORT = 80 # Port client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = (HOST, PORT) client_socket.connect(server_address) request_header = b'GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n' client_socket.sendall(request_header) response = '' while True: recv = client_socket.recv(1024) if not recv: break response += str(recv) 

Преузми ХТТП протокол и постави га на следећи начин:

正 则 表达式

正 则 表达式 (РЕ, или Регек) 是 字符串 的 搜索 模式。 你 可以 使用 регек 在 更大 的 文本 中 搜索 搜索 特定 的 或 或 单词 , 例如 , 你 可以 识别 识别 网页 你 也 可以 可以 轻松 地 地替换 字符串 , 例如 , 可以 将 格式 的 ХТМЛ ХТМЛ 中 的 所有 大写 标记 用 小写 标记 标记。 还 可以 可以 验证。。。

你 可能 想 知道 , 为什么 在进行 Веб 抓取 时 了解 正 则 表达式 很? 毕竟 毕竟 , 各种 的 的 Питхон 模块 来 解析 ХТМЛ 、 КСПатх 和 ЦСС 选择 器。

在 一个 理想 的 语义 世界 中 , 数据 很 容易 被 机器 读取 信息 信息 被 嵌入 到 的 ХТМЛ ХТМЛ 元素 ​​和 具有 一定 意义 的 属性 属性。。

但 现实 世界 是 混乱 的 , 你 会 在 п 元素 中 搜索 大量 的 文本。 当 你 想要 在 这个 这个 巨大 的 文本 块 中 提取 特定 特定 数据 (价格 价格 、 、 日期 或 名称 正 则 则 则 则

注意这篇 文章 只 介绍 了 小 你 你 可以 可以 做 做 做 做 做 的 ​​的 的 通过 通过 通过 通过 通过 通过 通过 通过 通过 则 则 则 则 则 则 则 则 则。。。。。。。。

你 的 数据 类似于 下面 这种 正 正 正 正 正 作用 作用 作用:

Price : 19.99$

使用 атх 使用 КСПатх 表达式 选择 这个 文本 节点 , 然后 使用 这种 регек 提取 цена。 请 记住 , 正 则 表达式 模式 模式。。。。:

^Price\s:\s(\d+.\d{2})$ 

Преузми ХТМЛ регекс, регуларни израз, који садржи:

import re html_content = '

Price : 19.99$

'

如 你 所见 , 通过 цкет соцкет 手动 发送 ХТТП 请求 并 使用 正 则 表达式 解析 响应 是 可以 完成 的 但这 很 的 的 АПИ 可以 使 这个 任务 的 更。。。

урллиб3 и ЛКСМЛ

说明: 我们 在 Питхон 中 的 урллиб 系列 的 库 的 时候 很 容易 感到 迷茫 иПитхон 除了 有 作为 库 一部分 的 урлиб 和 урлиб2 还有 ли урлиб3。урллиб2 在 Питхон3 中 被 分成 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 很多 ли ли ли 3 3 3 3 3 3不会 成为 标准 库 的 一部分。 其实 应该 有 一篇 单独 文章 来 这些 这些 令人 困惑 的 细节 在 在 本篇 中 л урллиб 3 , 因为 它 在 Питхон 世界 中 被 广泛 使用。。

урллиб3 не користи ХТТП ХТТП протокол, а користи га у: 操作 来 操作 操作:

import urllib3 http = urllib3.PoolManager() r = http.request('GET', '//www.google.com') print(r.data) 

比套接字版本要简洁得多,对吗?不仅如此,API 也很简单,你可以轻松地做许多事情,比如添加 HTTP 头、使用代理、发布表单等等。

例如,如果我们必须设置一些 header 字段来使用代理,我们只需这样做:

import urllib3 user_agent_header = urllib3.make_headers(user_agent="") pool = urllib3.ProxyManager(f'', headers=user_agent_header) r = pool.request('GET', '//www.google.com/') 

看见没?完全相同的行数。

然而,有些事情 urllib 3并不容易处理。如果要添加 cookie,则必须手动创建相应的 header 字段并将其添加到请求中。

此外,urllib 3 还可以做一些请求不能做的事情,比如池和代理池的创建和管理,以及重试策略的控制。

简单地说,urllib 3 在抽象方面介于请求和套接字之间,尽管它比套接字更接近请求。

为了解析响应,我们将使用 lxml 包和 XPath 表达式。

XPath

XPath 是一种使用路径表达式在 XML 或 HTML 文档中选择节点或节点集的技术。与文档对象模型(DocumentObjectModel)一样,XPath 自 1999 年以来一直是 W3C 标准。即使 XPath 本身不是一种编程语言,它允许你编写可以直接访问特定节点或节点集的表达式,而无需遍历整个 XML 或 HTML 树。

可以将 XPath 看作一种专门用于 XML 或 HMTL 的正则表达式。

要使用 XPath 从 HTML 文档中提取数据,我们需要 3 件事:

  • HTML 文档
  • 一些 XPath 表达式
  • 运行这些表达式的 XPath 引擎

首先,我们将使用我们通过 urllib 3 获得的 HTML。我们只想从 Google 主页中提取所有链接,所以我们将使用一个简单的 XPath 表达式 //a ,并使用 LXML 来运行它。LXML 是一个快速易用的 XML 和 HTML 处理库,支持 XPath。

安装 :

pip install lxml 

下面是前面片段之后的代码:

from lxml import html 

输出如下:

//books.google.fr/bkshp?hl=fr&tab=wp //www.google.fr/shopping?hl=fr&source=og&tab=wf //www.blogger.com/?tab=wj //photos.google.com/?tab=wq&pageId=none //video.google.fr/?hl=fr&tab=wv //docs.google.com/document/?usp=docs_alc ... //www.google.fr/intl/fr/about/products?tab=wh 

请记住,这个示例非常简单,并没有向你展示 XPath 有多强大。 (注意: 这个 XPath 表达式应该更改为 //a/@href 为了避免在 links 中迭代以获得它们的 href )。

如果你想了解更多关于 XPath 的知识,可以阅读这个很棒的介绍文档。这个 LXML 文档 也编写得很好,很适合基础阅读。.

XPath 表达式和 regexp 一样很强大,是从 HTML 中提取信息的最快方法之一。虽然 XPath 也像 regexp 一样很快就会变得凌乱,难以阅读和维护。

requests & BeautifulSoup(库)

下载量已经超过 11,000,000 次的 Requests 库是 Python 包中的佼佼者,它是 Python 使用最广泛的包。

安装:

pip install requests 

使用 Requests 库发送一个请求是非常容易的事情:

import requests 

使用 Requests 库可以很容易地执行 POST 请求、处理 cookie 和查询参数。

Hacker News 认证

假设我们想要创建一个工具来自动提交我们的博客文章给 Hacker News 或任何其他论坛如 Buffer。在提交我们的链接之前,我们需要认证到这些网站。这就是我们要通过 Requests 和 BeautifulSoup 做的事情!

下面是 Hacker News 登录表单和相关的 DOM:

这个表单上有三个 标签。第一个带有 hidden 类型的名字为 “goto” 输入,另外两个是用户名和密码。

如果你在 Chrome 浏览器中提交表单,你会发现有很多事情发生:重定向和正在设置 cookie。这个 cookie 将由 Chrome 在每个后续请求上发送,以便服务器知道你已通过身份验证。

通过 Requests 来做这些工作将会变得非常简单,它将自动为我们处理重定向,而处理 cookie 则可以使用 _Session_Object 完成。

接下来我们需要的是 BeautifulSoup,它是一个 Python 库,它将帮助我们解析服务器返回的 HTML,以确定我们是否登录。

安装:

pip install beautifulsoup4 

所以我们要做的就是通过 POST 请求将这三个带有我们登录凭证的输入发送到 /login 终端,并且验证一个只在登录成功时才出现的元素。

import requests from bs4 import BeautifulSoup BASE_URL = '//news.ycombinator.com' USERNAME = "" PASSWORD = "" s = requests.Session() data = {"gogo": "news", "acct": USERNAME, "pw": PASSWORD} r = s.post(f'{BASE_URL}/login', data=data) 

我们可以尝试提取主页上的每一个链接,以了解更多关于 BeautifulSoup 的信息。

顺便说一句,Hacker News 提供了一个功能强大的 API,所以我们这里只是以它为例,你真的应该直接使用 API,而不是爬取它! _

我们需要做的第一件事是观察分析Hacker News主页,以了解我们必须选择的结构和不同的 CSS 类。

我们可以看到所有的 posts 都在 里 ,因此,我们需要做的第一件事是选择所有这些标记。通过下面这行代码我们很容易实现:

links = soup.findAll('tr', class_="athing") 

然后,对于每个链接,我们将提取其 ID、标题、url 和排名:

import requests from bs4 import BeautifulSoup r = requests.get('//news.ycombinator.com') soup = BeautifulSoup(r.text, 'html.parser') links = soup.findAll('tr', class_="athing") formatted_links = [] for link in links: data = { 'id': link['id'], 'title': link.find_all('td')[2].a.text, "url": link.find_all('td')[2].a['href'], "rank": int(links[0].td.span.text.replace('.', '')) } formatted_links.append(data) 

正如你所看到的,Requests 和 BeautifulSoup 是提取数据和自动化实现各种操作(如填写表单)的很好的库。如果你想做大规模的网络抓取项目,你仍然可以使用请求,但你需要自己处理很多事情。

在爬取大量网页的时候,你需要处理很多事情:

  • 找到并行化代码的方法,使代码更高效
  • 处理错误
  • 存储爬取的数据
  • 过滤和筛选数据
  • 控制请求速度,这样就不会使服务器超载

幸运的是,我们可以使用工具处理所有这些事情。

Scrapy

scrapy 是一个强大的 Python Web 抓取框架。它提供了许多特性来异步下载、处理和保存网页。它处理多线程、爬行(从链接到查找网站中的每个URL的过程)、站点地图爬行等等。

Scrapy 还有一个名为 ScrapyShell 的交互模式。你可以使用 ScrapyShell 快速测试代码,比如 XPath 表达式或 CSS 选择器。

Scrapy 的缺点在于陡峭的学习曲线——有很多东西要学。

继续上述 Hacker News 的例子,我们将编写一个 ScrapySpider,它会抓取前 15 页的结果,并将所有内容保存在 CSV 文件中。

pip 安装 Scrapy:

pip install Scrapy 

然后,你可以使用 scrapycli 生成项目的样板代码:

scrapy startproject hacker_news_scraper 

hacker_news_scraper/spider 我们将使用Spider的代码创建一个新的 Python 文件:

from bs4 import BeautifulSoup import scrapy class HnSpider(scrapy.Spider): name = "hacker-news" allowed_domains = ["news.ycombinator.com"] start_urls = [f'//news.ycombinator.com/news?p={i}' for i in range(1,16)] def parse(self, response): soup = BeautifulSoup(response.text, 'html.parser') links = soup.findAll('tr', class_="athing") for link in links: yield { 'id': link['id'], 'title': link.find_all('td')[2].a.text, "url": link.find_all('td')[2].a['href'], "rank": int(link.td.span.text.replace('.', '')) }

Scrapy中有很多规定.这里我们定义了一个启动URL数组。属性name将用于使用Scrapy命令行调用我们的Spider。

start_urls 数组中的每个URL调用解析方法

然后,为了让我们的爬虫更好的在目标网站上爬数据,我们要对Scrapy进行微调。

# Enable and configure the AutoThrottle extension (disabled by default)See //doc.scrapy.org/en/latest/topics/autothrottle.html AUTOTHROTTLE_ENABLED = True The initial download delay 

你应该一直把这个爬虫程序一直运行着,它将通过分析响应时间和调整并发线程的数量来确保目标网站不会因为爬虫而负载过大。

你可以使用 ScrapyCLI 运行下面的代码并且设置不同的输出格式(CSV、JSON、XML等)。

scrapy crawl hacker-news -o links.json 

类似于这样,最终爬取的结果会按照 json 的格式导出到一个名为 links 的 json 文件中

Selenium & Chrome —headless

对于大规模的网络抓取任务来说,Scrapy 是非常好的。但是,如果需要爬取用 JavaScript 框架编写的单页应用程序,这是不够的,因为它无法呈现 JavaScript 代码。

爬取这些 SPAs 是很有挑战性的,因为经常涉及很多 Ajax 调用和 WebSocket 连接。如果性能存在问题,你将不得不逐个复制 JavaScript 代码,这意味着使用浏览器检查器手动检查所有网络调用,并复制和你感兴趣的数据相关的 Ajax 调用。

在某些情况下,涉及到的异步 HTTP 调用太多,无法获取所需的数据,在 headless 模式的浏览器中呈现页面可能会更容易。

另一个很好的用例是对一个页面进行截图。这是我们将要对 Hacker News 主页做的事情(再次!)pip 安装 Selenium 包:

pip install selenium 

需要 还 需要 Цхромедривер:

brew install chromedriver 

然后 , 我们 只需 从 ниум ниум 中 导入 ри ри ри ри ри ри ри ри ри ри ри 的 的 的 的 Цхроме 大小 Хеадлесс = Труе , 并 并 设置 一个 窗口 大小):

from selenium import webdriver from selenium.webdriver.chrome.options import Options 

然后 你 应该 得到 一个 很好 的 主页。。

你 可以 使用 СелениумАПИ, Цхроме 做 更多 的 事情 比如 比如:

  • 执行 ЈаваСцрипт
  • 填写 表单
  • 点击 元素
  • 用 ЦСС 选择 器 或 КСПатх 表达式 提取 元素

Селен, безглави, Цхроме, Цхроме, Цхроме, Цхроме, Цхроме, Цхроме, Цхроме

Цхроме 最大 的 缺点 需要 需要 大量 内存 / ЦПУ 能力。 通过 一些 微调 , 你 你 可以 每个 Цхроме Цхроме 实例 实例 内存 占用 到 减少 300-400МБ , 但 每个 实例 仍然 需要 需要 ЦПУ 需要

如果 你 想 同时 运行 多个 Цхроме Цхроме 实例 , 将 将 需要 强大 的 服务器 (其 成本 成本 迅速 迅速 , 以及 以及。。

总结

我 希望 这个 概述 将 帮助 你 的 的 Питхон 抓取 工具 , 并 希望 你 通过 本文 能 有所 有所

我 在 这篇 文章 中 所 介绍 的 工具 都是 我 在 做 自己 项目 СцрапингНиња 时 用过 的 , 这个 项目 很 简单 的 网络 АПИ АПИ

这篇 文章 中 提及 的 每 一个 工具 , 我 之后 都会 单独 写 一篇 博客 来 来 进行 深入 阐述。。

不要 犹豫 , 在 评论 中 告诉 我 你 知道 知道 关于 爬虫 的 哪些 知识。 我 我 将会 一篇 文章 文章 文章。。。

Срећно стругање!

Адреса: //ввв.фреецодецамп.орг/невс/веб-сцрапинг-101-ин-питхон/ Адреса: Пиерре де Вулф