调试ScraperWiki scraper(产生虚假整数)

时间:2013-05-06 10:44:32

标签: python screen-scraping scraperwiki

这是我在ScraperWiki上使用Python创建的一个scraper:

import lxml.html
import re
import scraperwiki

pattern = re.compile(r'\s')
html = scraperwiki.scrape("http://www.shanghairanking.com/ARWU2012.html")
root = lxml.html.fromstring(html)
for tr in root.cssselect("#UniversityRanking tr:not(:first-child)"):
    if len(tr.cssselect("td.ranking")) > 0 and len(tr.cssselect("td.rankingname")) > 0:
        data = {
            'arwu_rank'  : str(re.sub(pattern, r'', tr.cssselect("td.ranking")[0].text_content())),
            'university' : tr.cssselect("td.rankingname")[0].text_content().strip()
        }
    # DEBUG BEGIN
    if not type(data["arwu_rank"]) is str:
        print type(data["arwu_rank"])
        print data["arwu_rank"]
        print data["university"]
    # DEBUG END
    if "-" in data["arwu_rank"]:
        arwu_rank_bounds  = data["arwu_rank"].split("-")
        data["arwu_rank"] = int( ( float(arwu_rank_bounds[0]) + float(arwu_rank_bounds[1]) ) * 0.5 )
    if not type(data["arwu_rank"]) is int:
        data["arwu_rank"] = int(data["arwu_rank"])
    scraperwiki.sqlite.save(unique_keys=['university'], data=data)

除了刮取表格的最后一行数据(“约克大学”行)之外,它的工作方式非常完美,此时不是代码的第9到11行,而是从代码中检索字符串“401-500”表并分配给data["arwu_rank"],这些行似乎在某种程度上导致将450分配给data["arwu_rank"]。您可以看到我添加了几行“调试”代码,以便更好地了解正在发生的事情,而且调试代码也不是很深入。

我有两个问题:

  1. 我可以选择调试在ScraperWiki基础架构上运行的scraper,例如:对于这样的故障排除问题?例如。有没有办法逐步完成?
  2. 你能告诉我为什么将450而不是字符串“401-500”分配给“约翰大学”专栏的data["arwu_rank"]
  3. 编辑2013年5月6日,20:07h UTC

    以下刮刀完成没有问题,但我仍然不确定为什么第一个在“约克大学”线上失败:

    import lxml.html
    import re
    import scraperwiki
    
    pattern = re.compile(r'\s')
    html = scraperwiki.scrape("http://www.shanghairanking.com/ARWU2012.html")
    root = lxml.html.fromstring(html)
    for tr in root.cssselect("#UniversityRanking tr:not(:first-child)"):
        if len(tr.cssselect("td.ranking")) > 0 and len(tr.cssselect("td.rankingname")) > 0:
            data = {
                'arwu_rank'  : str(re.sub(pattern, r'', tr.cssselect("td.ranking")[0].text_content())),
                'university' : tr.cssselect("td.rankingname")[0].text_content().strip()
            }
            # DEBUG BEGIN
            if not type(data["arwu_rank"]) is str:
                print type(data["arwu_rank"])
                print data["arwu_rank"]
                print data["university"]
            # DEBUG END
            if "-" in data["arwu_rank"]:
                arwu_rank_bounds  = data["arwu_rank"].split("-")
                data["arwu_rank"] = int( ( float(arwu_rank_bounds[0]) + float(arwu_rank_bounds[1]) ) * 0.5 )
            if not type(data["arwu_rank"]) is int:
                data["arwu_rank"] = int(data["arwu_rank"])
            scraperwiki.sqlite.save(unique_keys=['university'], data=data)
    

1 个答案:

答案 0 :(得分:2)

在ScraperWiki上调试脚本没有简单的方法,遗憾的是它只是完整地发送你的代码并得到结果,没有办法以交互方式执行代码。

我在代码副本中添加了几个打印件,看起来像分配数据之前的if检查

if len(tr.cssselect("td.ranking")) > 0 and len(tr.cssselect("td.rankingname")) > 0:

不会触发“约克大学”,因此它将保持前一个循环周期内的int值(稍后设置)。