【问题标题】:Submit data via web form and extract the results通过网络表单提交数据并提取结果
【发布时间】:2012-01-12 16:56:28
【问题描述】:

我的python级别是新手。我从来没有写过网络爬虫或爬虫。我已经编写了一个 python 代码来连接到一个 api 并提取我想要的数据。但是对于一些提取的数据,我想得到作者的性别。我找到了这个网站http://bookblog.net/gender/genie.php,但缺点是没有可用的 api。我想知道如何编写一个python来向页面中的表单提交数据并提取返回数据。如果我能在这方面得到一些指导,那将是一个很大的帮助。

这是 dom 的形式:

<form action="analysis.php" method="POST">
<textarea cols="75" rows="13" name="text"></textarea>
<div class="copyright">(NOTE: The genie works best on texts of more than 500 words.)</div>
<p>
<b>Genre:</b>
<input type="radio" value="fiction" name="genre">
fiction&nbsp;&nbsp;
<input type="radio" value="nonfiction" name="genre">
nonfiction&nbsp;&nbsp;
<input type="radio" value="blog" name="genre">
blog entry
</p>
<p>
</form>

结果页面 dom:

<p>
<b>The Gender Genie thinks the author of this passage is:</b>
male!
</p>

【问题讨论】:

    标签: python web-crawler web-scraping


    【解决方案1】:

    无需使用 mechanize,只需在 POST 请求中发送正确的表单数据即可。

    另外,使用正则表达式解析 HTML 是一个坏主意。最好使用像 lxml.html 这样的 HTML 解析器。

    import requests
    import lxml.html as lh
    
    
    def gender_genie(text, genre):
        url = 'http://bookblog.net/gender/analysis.php'
        caption = 'The Gender Genie thinks the author of this passage is:'
    
        form_data = {
            'text': text,
            'genre': genre,
            'submit': 'submit',
        }
    
        response = requests.post(url, data=form_data)
    
        tree = lh.document_fromstring(response.content)
    
        return tree.xpath("//b[text()=$caption]", caption=caption)[0].tail.strip()
    
    
    if __name__ == '__main__':
        print gender_genie('I have a beard!', 'blog')
    

    【讨论】:

    • 我尝试做easy_install lxml.html,但得到以下错误easy_install lxml.html Searching for lxml.html Reading pypi.python.org/simple/lxml.html Couldn't find index page for 'lxml.html'(可能拼写错误? )扫描所有包的索引(这可能需要一段时间)阅读pypi.python.org/simple没有找到lxml.html错误的本地包或下载链接:找不到Requirement.parse('lxml.html')的合适分发
    • 在一个模块导入中,如果两个名称之间有一个.,则表示第二个名称在前一个名称中。你要安装的模块是lxml。
    • 谢谢我在发表评论后意识到了这一点。谢谢阿吉安
    • POST是什么方法?
    【解决方案2】:

    您可以使用mechanize 提交和检索内容,并使用re 模块获取您想要的内容。例如,下面的脚本为您自己的问题文本执行此操作:

    import re
    from mechanize import Browser
    
    text = """
    My python level is Novice. I have never written a web scraper 
    or crawler. I have written a python code to connect to an api and 
    extract the data that I want. But for some the extracted data I want to 
    get the gender of the author. I found this web site 
    http://bookblog.net/gender/genie.php but downside is there isn't an api 
    available. I was wondering how to write a python to submit data to the 
    form in the page and extract the return data. It would be a great help 
    if I could get some guidance on this."""
    
    browser = Browser()
    browser.open("http://bookblog.net/gender/genie.php")
    
    browser.select_form(nr=0)
    browser['text'] = text
    browser['genre'] = ['nonfiction']
    
    response = browser.submit()
    
    content = response.read()
    
    result = re.findall(
        r'<b>The Gender Genie thinks the author of this passage is:</b> (\w*)!', content)
    
    print result[0]
    

    它有什么作用?它会创建一个mechanize.Browser 并转到给定的 URL:

    browser = Browser()
    browser.open("http://bookblog.net/gender/genie.php")
    

    然后它选择表格(因为只有一个表格要填写,所以它将是第一个):

    browser.select_form(nr=0)
    

    此外,它还设置表单的条目...

    browser['text'] = text
    browser['genre'] = ['nonfiction']
    

    ...并提交:

    response = browser.submit()
    

    现在,我们得到了结果:

    content = response.read()
    

    我们知道结果是这样的:

    <b>The Gender Genie thinks the author of this passage is:</b> male!
    

    所以我们创建一个正则表达式进行匹配并使用re.findall()

    result = re.findall(
        r'<b>The Gender Genie thinks the author of this passage is:</b> (\w*)!',
        content)
    

    现在结果可供您使用:

    print result[0]
    

    【讨论】:

    • 非常感谢,对于像我这样的新 b 来说,这是一个很好的答案,很好的解释。希望我可以多次投票...... ;)
    【解决方案3】:

    您可以使用mechanize,详情请参阅examples

    from mechanize import ParseResponse, urlopen, urljoin
    
    uri = "http://bookblog.net"
    
    response = urlopen(urljoin(uri, "/gender/genie.php"))
    forms = ParseResponse(response, backwards_compat=False)
    form = forms[0]
    
    #print form
    
    form['text'] = 'cheese'
    form['genre'] = ['fiction']
    
    print urlopen(form.click()).read()
    

    【讨论】:

    • 非常感谢您的回复。听起来 machanize 是我安装的模块?在终端上快速测试得到没有模块错误。我不是 mac,我应该可以通过 easy_install 来获得 machanize。
    • 哦,对了,它是一个外部模块。是的,你可以做 easy_install mechanize。
    猜你喜欢
    • 2012-11-17
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多