【问题标题】:output more than limited results from a form request从表单请求中输出超过有限的结果
【发布时间】:2014-12-01 12:56:02
【问题描述】:

我有以下脚本将搜索词发布到表单中并检索结果:

import mechanize

url = "http://www.taliesin-arlein.net/names/search.php"
br = mechanize.Browser()
br.set_handle_robots(False) # ignore robots
br.open(url)
br.select_form(name="form")
br["search_surname"] = "*"
res = br.submit()
content = res.read()
with open("surnames.txt", "w") as f:
    f.write(content)

然而,渲染的网页,因此这里的脚本将搜索限制为 250 个结果。有什么方法可以绕过此限制并检索所有结果?

谢谢

【问题讨论】:

  • 我不确定我是否理解您的问题:网络请求仅返回 250 个结果?
  • 您有两种可能: 1 给 www.taliesin-arlein.net 的站长写一封邮件,询问所有结果; 2 入侵该网站并窃取所有姓氏.... 说真的:我觉得脚本不接受任何参数来更改答案的最大大小。
  • 大声笑不想偷任何东西。我假设既然可以通过网站允许的重复查询来获取所有数据,那么也许会有某种方法可以将所有数据合二为一。是的,网络请求只返回前 250 个结果。
  • 不幸的是,表单使用通配符而不是序列或间隔定义。您可以通过最后一个答案来做到这一点,并通过移动通配符进行另一个呼叫。这有点乏味而且不是很有趣,但它应该可以工作。我不会为它提交答案。

标签: python html forms curl web-scraping


【解决方案1】:

您可以简单地遍历可能的前缀来绕过限制。每个查询有 270,000 个名称和 250 个结果的限制,因此您需要至少发出 1080 个请求,字母表中有 26 个字母,所以如果我们假设分布均匀,这意味着我们需要使用多一点2 个字母作为前缀 (log(1080)/log(26)),但不太可能是这样(毕竟有多少人的姓氏以 ZZ 开头)。

为了解决这个问题,我们使用修改后的深度优先搜索,如下所示:

import string
import time
import mechanize

def checkPrefix(prefix):
    #Return list of names with this prefix.
    url = "http://www.taliesin-arlein.net/names/search.php"
    br = mechanize.Browser()
    br.open(url)
    br.select_form(name="form")
    br["search_surname"] = prefix+'*'
    res = br.submit()
    content = res.read()
    return extractSurnames(content)

def extractSurnames(pageText):
    #write function to extract text from html


Q=[x for x in string.ascii_lowercase]
listOfSurnames=[]
while Q:
    curPrefix=Q.pop()
    print curPrefix
    curSurnames=checkPrefix(curPrefix)
    if len(curSurnames)<250:
        #store surnames could also write to file.
        listOfSurnames+=curSurnames
    else:
        #We clearly didnt get all of the names need to subdivide more
        Q+=[curPrefix+x for x in string.ascii_lowercase]
    time.sleep(5) # Sleep here to avoid overloading the server for other people.

因此,我们在要显示的结果过多的地方查询更多,但如果以 ZZZ(或更短)开头的姓氏少于 250 个,我们不会查询 ZZZZ。在不知道名称分布有多倾斜的情况下,很难估计这需要多长时间,但 5 秒的睡眠乘以 1080 是 1.5 小时左右,因此您可能至少需要半天时间。

注意:这可以通过全局声明浏览器来提高效率,但是这是否合适取决于此代码的放置位置。

【讨论】:

  • 哇——太棒了。将不得不吸收它,但是您甚至想到了分配不均,这将不可避免地发挥作用。非常感谢 - 这将有助于阅读。
猜你喜欢
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 2021-05-07
  • 2018-01-09
  • 2014-01-10
相关资源
最近更新 更多