9

我正在尝试使用 mechanize 在网站上解析和提交表单,但似乎内置表单解析器无法检测到表单及其元素。我怀疑它对格式不正确的 HTML 感到窒息,我想尝试使用更好地设计用于处理错误 HTML(例如 lxml 或 BeautifulSoup)的解析器对其进行预解析,然后将经过美化、清理的输出提供给表单解析器。我不仅需要机械化提交表单,还需要维护会话(我在登录会话中处理此表单。)

如果确实可能的话,我不知道该怎么做。我对HTTP协议的各种细节,如何使各个部分协同工作等不太熟悉。任何指针?

4

3 回答 3

10

我遇到了表单中缺少表单字段的问题,我找不到任何格式错误的 html,但我认为这是原因,所以我使用 BeautifulSoup 的 prettify 函数来解析它并且它有效。

resp = br.open(url)
soup = BeautifulSoup(resp.get_data())
resp.set_data(soup.prettify())
br.set_response(resp)

我很想知道如何自动做到这一点。

编辑:了解如何自动执行此操作

class PrettifyHandler(mechanize.BaseHandler):
    def http_response(self, request, response):
        if not hasattr(response, "seek"):
            response = mechanize.response_seek_wrapper(response)
        # only use BeautifulSoup if response is html
        if response.info().dict.has_key('content-type') and ('html' in response.info().dict['content-type']):
            soup = BeautifulSoup(response.get_data())
            response.set_data(soup.prettify())
        return response

    # also parse https in the same way
    https_response = http_response

br = mechanize.Browser()
br.add_handler(PrettifyHandler())

br现在将BeautifulSoup用于解析内容类型(mime 类型)中包含 html 的所有响应,例如text/html

于 2011-02-18T09:27:11.523 回答
3

从mechanize 网站第一页的大例子中阅读:

# Sometimes it's useful to process bad headers or bad HTML:
response = br.response()  # this is a copy of response
headers = response.info()  # currently, this is a mimetools.Message
headers["Content-type"] = "text/html; charset=utf-8"
response.set_data(response.get_data().replace("<!---", "<!--"))
br.set_response(response)

因此似乎很有可能使用另一个解析器预处理响应,该解析器将重新生成格式良好的 HTML,然后将其反馈回机械化以进行进一步处理。

于 2009-11-23T15:13:27.173 回答
1

您正在寻找的可以通过以下方式提供lxml.etreexml.etree.ElementTree模拟器(和替换)来完成lxml

首先,我们采用格式错误的 HTML:

% cat bad.html
<html>
<HEAD>
    <TITLE>this HTML is awful</title>
</head>
<body>
    <h1>THIS IS H1</H1>
    <A HREF=MYLINK.HTML>This is a link and it is awful</a>
    <img src=yay.gif>
</body>
</html>

(注意开始和结束标签之间的大小写混合,缺少引号)。

然后解析它:

>>> from lxml import etree
>>> bad = file('bad.html').read()
>>> html = etree.HTML(bad)
>>> print etree.tostring(html)
<html><head><title>this HTML is awful</title></head><body>
    <h1>THIS IS H1</h1>
    <a href="MYLINK.HTML">This is a link and it is awful</a>
    <img src="yay.gif"/></body></html>

请注意标记和报价已为我们更正。

如果您之前在解析 HTML 时遇到问题,这可能就是您正在寻找的答案。至于 HTTP 的细节,那完全是另外一回事。

于 2009-11-23T15:14:38.903 回答