机械化不行! 在这种情况下,美丽的汤幸福快乐☆
目录
你好。
我叫 Bandai,负责《Wild》的开发团队。
这次,我们将很高兴使用 Mechanize(在使用 Python 抓取时经常使用)和 Beautiful Soup(一个用于分析 HTML 的库)进行抓取。我想继续这个目标。
Beautiful Soup本身并没有解决Mechanize的问题,所以这个标题有点夸张,但是没关系。
什么是美汤?
Beautiful Soup 是一个提供 HT(X)ML 解析器功能的 Python 库。
由于它只提供解析器功能,因此有些部分可以单独使用 Mechanize 解决,但
Beautiful Soup 的美妙之处在于它还可以分析 Mechanize 无法分析的 HTML。
我将思考如何有效地使用 Beautiful Soup 和 Mechanize 来轻松消除 Mechanize 无法使用 Beautiful Soup 解析的 HTML
这次,我们将继续使用Python 2.7系列。
准备必要的库
使用 pip 获取所需的库。
pip install mechanize beautifulsoup4 # 必要时请使用sudo # 小心,如果使用beautifulsoup会安装Beautiful Soup3系列 # 顺便说一下,在我的环境中,3和4几乎无处不在并存。
如何分析 Mechanize with Beautiful Soup 拾取的 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([your markup], "lxml") markup_type=markup_type))
要指定 lxml 来解析 HTML,请指定如下。
汤 = BeautifulSoup(br.response().read(), "lxml")
将Beautiful Soup解析后的HTML返回给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 行,形式 self._forms_factory.forms()) 文件“/usr/local/lib/python2.7/site-packages/mechanize/_html.py”,第 237 行,形式 _urlunparse=_rfc3986.urlunsplit,文件“/usr/local/lib/python2.7/site-packages/mechanize/_form.py”,第 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 行,提要 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 ,方法,attrs)文件“/usr/local/lib/python2.7/site-packages/mechanize/_sgmllib_copy.py”,第387行,在handle_starttag方法(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("SELECT 之外的选项") mechanize._form.ParseError: SELECT 之外的选项
在这些情况下,我通常无法解析它,最终放弃并寻找另一种方法,所以
我让Beautiful Soup对其进行分析,仅提取和处理必要的形式,然后将其发送回Mechanize,然后我可以让我们继续吧。
(错误本身,SELECT 之外的 OPTION,似乎是一个错误,其中 select 标签外部有一个选项标签(或者 select 标签内部没有选项标签))
这次,select 标签中没有选项标签,因此我将添加一个包含 Beautiful Soup 的选项标签,然后将其返回给 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 = o.option # 添加选项标签到表单中的选择标签 f.find(id='target_select').append(option) # 机械化响应 创建一个对象并将其注册到Mechanize response = mechanize.make_response(str(f), [("Content-Type", "text/html")], br.geturl(), 200, "OK") br. set_response(response) # 尝试指定表单与机械化 br.select_form(nr=0)
我很难找到一个日本网站,上面说可以使用 mechanize.make_response() 和 set_response() 将 Beautiful Soup 解析的 HTML 返回给 Mechanize,但我通过参考这个网站解决了这个问题。
使用 Mechanize 和 Beautifulsoup 进行表单处理 · Todd Hayton
虽然是英文网站,但是还有其他详细信息,主要是关于如何使用Mechanize,所以你可以学到很多东西。
就是这样。