python - 第一个python脚本,刮板,欢迎使用建议

标签 python mechanize lxml scraper

我刚刚完成了我的第一个Python脚本,一个从菲律宾选举数据的铲运机。我没有编程背景,我已经使用STATA进行统计分析,最近在R中涉猎了一点,因为我想在某个时候切换。但我想学习Python从网站和其他来源提取数据。到目前为止,我只浏览了Python教程,奥利利正在学习“Python”。我写了下面的脚本,灵感来自其他人的脚本和浏览包含的包文档。
我基本上寻找的是一般的建议。剧本确实有用,但有多余的部分吗?我应该换个结构吗?有什么典型的(或明显的哑巴)初学者的错误吗?
我自己编了几个问题,在剧本后面列出了。

import mechanize
import lxml.html
import csv

site = "http://www.comelec.gov.ph/results/2004natl/2004electionresults_local.aspx"

br = mechanize.Browser()
response = br.open(site)

output = csv.writer(file(r'output.csv','wb'))


br.select_form(name="ctl00")
provinces = br.possible_items("provlist")

for prov in provinces:
    br.select_form(name="ctl00")
    br["provlist"] = [prov]
    response = br.submit()
    br.select_form(name="ctl00")
    pname = str(br.get_value_by_label("provlist")).strip("[]")
    municipalities = br.possible_items("munlist")
    for mun in municipalities:
        br.select_form(name="ctl00")
        br["munlist"] = [mun]
        response = br.submit(type="submit", name="ctl01")
        html = response.read()
        root = lxml.html.fromstring(html)
        try: 
            table = root.get_element_by_id(id="dlistCandidates")
            data = [
                       [td.text_content().strip() for td in row.findall("td")] 
                       for row in table.findall('tr')
                   ]
        except KeyError:
            print "Results not available yet."
            data = [ [ "." for i in range(5) ] ]
        br.select_form(name="ctl00")
        mname = str(br.get_value_by_label("munlist")).strip('[]')
        print pname, mname, data, "\n"
        for row in data:
            if row: 
                row.append(pname)
                row.append(mname)
                output.writerow([s.encode('utf8') if type(s) is unicode else s for s in row])

当我执行脚本时,我得到一个错误消息:“Debug警告:[It..No.No.Addio.No.item项中的名称”)。原因是什么,我应该担心吗?
我现在在省份数字键上循环,然后每次取名字。我是不是应该在开头编一本字典,然后在上面循环呢?
有没有一种简单的方法可以将“ene”字符(上面有波浪号)直接编码为正常的n?
每次替换“数据”时,我如何最好地收集所有东西,然后在结尾写一个CSV文件?那会是更好的解决办法吗?
网站需要相当长的时间来响应每个请求。获取所有数据大约需要一个小时。我可以通过执行脚本和连接省份列表来加快这一速度。如何在一个脚本中发送并行请求?我最终想从那个网站获得更多的数据,并且加速这个过程是很好的。
我试过beautifulsoup和lxml模块,但更喜欢lxml解决方案。对于这类任务,还有哪些模块通常是有用的?
是否有用于内置模块和其他模块的文档/帮助文件的中央寄存器?在我看来,到处散布的文件是有点不方便的。写帮助(东西)常常导致“找不到东西”。
任何建议和评论都非常感谢。英语不是我的母语,但我希望我尽量减少错误。

最佳答案

DeprecationWarning来自mechanize模块,在调用possible_items时发出。它提出了一个更好的方法来获得同样的效果。我不知道作者为什么不说得更清楚些。
我觉得没什么区别。
你可能想看看http://effbot.org/zone/unicode-convert.htm
对我来说,像你所做的那样,增量写作看起来很不错。相反,您可以创建一个行列表,在循环中附加到它,然后在最后一次性地编写整个过程;主要的优点是模块性略有增加。(假设您想进行同样的擦除,但以另一种方式使用结果;您可以更容易地重用代码。)
(a)如果远程站点需要很长时间来响应,并且所有的刮削都来自该远程站点,那么您确信用多个请求并行地访问它是否真的有帮助?(b)你可能想检查一下,有关网站的所有者不反对这种刮擦,这是出于礼貌,因为如果他们确实反对,那么他们可能会注意到你在做什么,并阻止你。我想既然是政府网站,他们可能就没问题了。(c)查看python标准库中的threadingmultiprocessing模块。
我不知道;对不起。
不(除非你算上谷歌)。
看来你做了一点来回确定省市。如果它们在脚本调用之间不发生变化,则可能在本地保存它们,而不是每次询问远程网站。(这一成果可能不值得付出努力——但您可能想衡量仅仅获取这些信息需要多长时间。)
您可以考虑将将将将一个html blob转换为候选列表(如果是这样的话)的代码提取为一个单独的函数。
您可以考虑将类似的内容提取到一个单独的函数中:

def select_item(br, form, listname, value, submit_form=None):
  br.select_form(form)
  br[listname] = [value]
  return br.submit(type="submit", name=(submit_form or form))

也许是这样的:
def get_name(br, formname, label):
br.select_form(formname)
  return str(br.get_value_by_label(label)).strip("[]")

关于python - 第一个python脚本,刮板,欢迎使用建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5633503/

相关文章:

javascript - 使用 urllib2 指示 Python 单击按钮

python - 如何获得 python 模块的点符号?

perl - 如何使用 Mechanize 查找网站是否正在读取 cookie?

ruby - 如何在 ruby​​ 中使用 Mechanize 和 XMLSimple 解析 XML?

python - 带有 lxml 子路径的 XPath 谓词?

python - 在 Python 中合并 2 个排序列表的有效解决方案

java到python的转换: x509/dsa/sha1withdsa crypto howto?

ruby-on-rails - Mechanize ruby无法看到linkedin中的所有内容

python - lxml 使用 cssselector 检索奇怪的元素

python - Python 2.6.x 的 XML/XSL 库的选择