Mechanize 行不通!那我们就用 Beautiful Soup 吧!

你好,
我是万代,Wild Team的开发团队负责人。

这次,我想使用流行的 Python 爬虫工具 Mechanize 和 HTML 解析库 Beautiful Soup,来鼓励大家快乐地进行网页抓取!
标题可能有点夸张,但请见谅,因为 Beautiful Soup 本身并不能解决 Mechanize 面临的问题。

什么是美丽汤?

Beautiful Soup 是一个提供 HTML(XML)解析功能的 Python 库。
由于它只提供解析功能,所以有些部分 Mechanize 也能处理,但
Beautiful Soup 的优势在于它可以解析 Mechanize 无法解析的 HTML。


我们将探讨如何有效地使用 Beautiful Soup 和 Mechanize 来解析 Mechanize 无法解析的 HTML

这次我们将使用 Python 2.7。

刮擦程序

准备必要的图书馆

使用 pip 获取所需的库。

pip install mechanize beautifulsoup4 # 必要时使用 sudo # 注意:输入 beautifulsoup 将安装 Beautiful Soup 3.0。 # 在我的环境中,3 和 4 都已安装。

 

如何使用 Beautiful Soup 解析 Mechanize 获取的 HTML 源代码

将 Mechanize 生成的 HTML 代码导入 Beautiful Soup 进行解析非常容易。

br.open('https://beyondjapan.com') soup = BeautifulSoup(br.response().read())

 

上述命令将从 https://beyondjapan.com 获取 HTML,并将结果对象用 Beautiful Soup 解析后放入 soup 中。

 

切换 Beautiful Soup 的解析器引擎

Beautiful Soup 允许您根据具体情况切换用于分析的解析器引擎。Beautiful
Soup 官方页面建议使用 lxml 以提高速度。
由于本次我们将使用 lxml 进行分析,因此我们将使用 pip 安装 lxml 库。

pip install lxml # 必要时请使用 sudo

 

在代码中调用 Beautiful Soup 时,你需要指定一个解析器引擎;
如果不指定,它将使用 Python 的标准 HTML 解析器。此时,
错误信息会显示在标准错误输出中。因此,如果你担心这个问题,
即使使用标准解析器,最好也指定一个解析器引擎。

# 当未指定解析器时执行 soup = BeautifulSoup(br.response().read())

 

解析没有问题,但我收到以下错误:

/usr/local/lib/python2.7/site-packages/bs4/__init__.py:166: UserWarning: 没有显式指定解析器,因此我使用了适用于此系统的最佳 HTML 解析器(“lxml”)。这通常不是问题,但如果您在其他系统或不同的虚拟环境中运行此代码,它可能会使用不同的解析器并导致不同的行为。要消除此警告,请将 BeautifulSoup([您的标记]) 更改为 BeautifulSoup([您的标记], "lxml") markup_type=markup_type))。

 

要使用 lxml 解析 HTML,请使用以下代码:

soup = BeautifulSoup(br.response().read(), "lxml")

 

使用 Beautiful Soup 将解析后的 H​​TML 返回给 Mechanize,然后继续爬取。

使用 Beautiful Soup 来解析 Mechanize 无法解析的 HTML,然后
根据解析结果导航到其他页面。

例如,当您想使用表单提交数据时,通常
会在以下位置遇到解析错误,从而导致一些问题。

br.select_form(nr=0) 回溯(最近一次调用):文件“/home/vagrant/workspace/mechanize_test/test3.py”,第 13 行,在<module>br.select_form(nr=0) 文件“/usr/local/lib/python2.7/site-packages/mechanize/_mechanize.py”,第 499 行,在 select_form 中 global_form = self._factory.global_form 文件“/usr/local/lib/python2.7/site-packages/mechanize/_html.py”,第 544 行,在 __getattr__ 中 self.forms() 文件“/usr/local/lib/python2.7/site-packages/mechanize/_html.py”,第 557 行,在 forms 中 self._forms_factory.forms()) 文件“/usr/local/lib/python2.7/site-packages/mechanize/_html.py”,第 237 行,在 forms 中 _urlunparse=_rfc3986.urlunsplit, 文件“/usr/local/lib/python2.7/site-packages/mechanize/_form.py”,第 10 行844,在 ParseResponseEx 中 _urlunparse=_urlunparse,文件“/usr/local/lib/python2.7/site-packages/mechanize/_form.py”,第 981 行,在 _ParseFileEx 中 fp.feed(data),文件“/usr/local/lib/python2.7/site-packages/mechanize/_form.py”,第 758 行,在 feed 中 _sgmllib_copy.SGMLParser.feed(self, data),文件“/usr/local/lib/python2.7/site-packages/mechanize/_sgmllib_copy.py”,第 110 行,在 feed 中 self.goahead(0),文件“/usr/local/lib/python2.7/site-packages/mechanize/_sgmllib_copy.py”,第 144 行,在 goahead 中 k = self.parse_starttag(i),文件“/usr/local/lib/python2.7/site-packages/mechanize/_sgmllib_copy.py”,第 302 行,在 parse_starttag 中 self.finish_starttag(tag, attrs) 文件“/usr/local/lib/python2.7/site-packages/mechanize/_sgmllib_copy.py”,第 347 行,在 finish_starttag 中 self.handle_starttag(tag, method, attrs) 文件“/usr/local/lib/python2.7/site-packages/mechanize/_sgmllib_copy.py”,第 387 行,在 handle_starttag 中 method(attrs) 文件“/usr/local/lib/python2.7/site-packages/mechanize/_form.py”,第 735 行,在 do_option 中 _AbstractFormParser._start_option(self, attrs) 文件"/usr/local/lib/python2.7/site-packages/mechanize/_form.py", 第 480 行,在 _start_option 中引发 ParseError("OPTION outside of SELECT") mechanize._form.ParseError: OPTION outside of SELECT

 

在这种情况下,解析通常会失败,迫使您放弃并寻找其他解决方案。
但您可以运行 Beautiful Soup 来解析表单,提取并处理必要的部分,然后将其返回给 Mechanize,这样您就可以顺利地继续操作。
(“SELECT 标签外存在 OPTION 标签”错误本身似乎意味着 select 标签外存在 option 标签(或者 select 标签内没有 option 标签)。)

这次 select 标签内没有 option 标签,所以我使用 Beautiful Soup 添加了 option 标签,然后切换回 Mechanize。

# 使用 Beautiful Soup 分析 HTML soup = BeautifulSoup(br.response().read(), 'lxml') # 提取表单标签 f = soup.find('form') # 为要添加的 HTML 标签创建一个 Beautiful Soup 对象 o = BeautifulSoup('<option value="hogehoge" selected>富加富加</option>', 'lxml') # 提取 option 标签部分 option = o.option # 将 option 标签添加到表单中的 select 标签 f.find(id='target_select').append(option) # 创建一个 Mechanize 响应对象并将其注册到 Mechanize response = mechanize.make_response(str(f), [("Content-Type", "text/html")], br.geturl(), 200, "OK") br.set_response(response) # 尝试在 Mechanize 中指定表单 br.select_form(nr=0)

 

我费了好大劲才找到一个日本网站,上面说可以使用 mechanize.make_response() 和 set_response() 将 Beautiful Soup 解析的 HTML 返回给 Mechanize,但我参考了这个网站,最终解决了这个问题。

使用 Mechanize 和 BeautifulSoup 处理表单 · Todd Hayton

虽然这是一个英文网站,但它也包含详细的信息,主要介绍如何使用 Mechanize,非常有教育意义。

就这样。

如果您想咨询开发专业人士

在 Beyond,我们将我们在系统开发方面的丰富经验、技术和专业知识与开源软件技术和云技术(如 AWS)相结合,以可靠的质量和卓越的性价比提供网络系统的合同开发服务。

我们还负责服务器端/后端开发和专有 API 协作开发,充分利用我们的技术和专业知识,为大规模、高负载的游戏、应用程序和数字内容构建和运营 Web 系统/应用程序基础设施。

如果您在开发项目方面遇到任何问题,请访问以下网站。

● Web系统开发
● 服务器端开发(API/数据库)

如果您觉得这篇文章有用,请点击【点赞】!
0
加载中...
0票,平均分:0.00/10
1,382
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

万代洋一

我的主要工作是开发社交游戏的Web API,但我也很荣幸能够从事其他各种工作,包括市场营销。
我在Beyond中的肖像权采用CC0协议。