机械化不行! 在这种情况下,美丽的汤幸福快乐☆
目录 [非表示]
你好。
我叫 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 获取所需的库。
1 | pip install mechanize beautifulsoup4 # 必要时请使用sudo # 小心,如果使用beautifulsoup会安装Beautiful Soup3系列 # 顺便说一下,在我的环境中,3和4几乎无处不在并存。 |
如何分析 Mechanize with Beautiful Soup 拾取的 HTML 源代码
将 Mechanize 获得的 HTML 导入到 Beautiful Soup 并解析它是非常容易的。
1 |
上面的命令将从 https://beyondjapan.com 检索 HTML,并且已经被 Beautiful Soup 解析的对象将被放入 soup 中。
切换 Beautiful Soup 的解析器引擎
Beautiful Soup 允许您根据情况切换用于分析的解析器引擎。
Beautiful Soup的官方页面似乎在速度方面推荐使用lxml。
这次我们将使用lxml进行分析,因此我们将使用pip安装lxml库。
1 | pip install lxml # sudo 如有必要 |
解析器引擎是在代码中调用Beautiful Soup时指定的,但
如果没有指定,将使用Python的标准HTML解析器。
有些错误会出现在标准错误中,所以如果您担心这一点,
我认为即使使用标准解析器也最好指定解析器引擎。
1 | # 不指定解析器执行时 soup = BeautifulSoup(br.response().read()) |
我可以毫无问题地解析它,但出现以下错误
1 | /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,请指定如下。
1 | 汤 = BeautifulSoup(br.response().read(), "lxml" ) |
将Beautiful Soup解析后的HTML返回给Mechanize,继续爬取
使用 Beautiful Soup 来解析 Mechanize 无法解析的 HTML 是很常见的,然后
根据解析的结果继续到下一个页面。
例如,当你想使用表单发送数据时,
通常会在以下地方遇到解析错误,尽管这并不清楚。
1 | 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。
1 | # 用 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,所以你可以学到很多东西。
就是这样。