0

这是我在 ScraperWiki 上使用 Python 创建的刮板:

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"],这些行似乎反而导致 int450被分配给data["arwu_rank"]。您可以看到我添加了几行“调试”代码以更好地了解正在发生的事情,但调试代码并没有深入。

我有两个问题:

  1. 我有哪些选项可以调试在 ScraperWiki 基础架构上运行的爬虫,例如解决此类问题?例如,有没有办法通过?
  2. 你能告诉我为什么 int 450,而不是字符串“401-500”,被分配给data["arwu_rank"]“York University”行吗?

编辑 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)
4

1 回答 1

2

在 ScraperWiki 上调试您的脚本没有简单的方法,不幸的是它只是将您的代码全部发送并返回结果,没有办法交互式地执行代码。

我在您的代码副本中添加了更多打印,它看起来像在分配数据的位之前进行 if 检查

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

不会为“York University”触发,因此它将保持循环前一次的 int 值(稍后设置)。

于 2013-05-06T11:38:52.983 回答