尝试自动从公共搜索中抓取搜索结果,但遇到了一些麻烦。 URL 的形式为
http://www.website.com/search.aspx?keyword=#&&page=1&sort=Sorting
当我点击页面时,访问此页面后,它会略有变化
http://www.website.com/search.aspx?keyword=#&&sort=Sorting&page=2
问题是,如果我尝试直接访问第二个链接而不首先访问第一个链接,我将被重定向到第一个链接。我目前的尝试是在 scrapy 中定义一长串 start_urls 。
class websiteSpider(BaseSpider):
name = "website"
allowed_domains = ["website.com"]
baseUrl = "http://www.website.com/search.aspx?keyword=#&&sort=Sorting&page="
start_urls = [(baseUrl+str(i)) for i in range(1,1000)]
目前,这段代码只是一遍又一遍地访问第一页。我觉得这可能很简单,但我不太知道如何解决这个问题。
更新:
对此进行了一些调查,发现站点通过使用 __doPostBack(arg1, arg2) 向前一页发送 POST 请求来更新每个页面。我现在的问题是如何使用 scrapy 模拟这个 POST 请求。我知道如何发出 POST 请求,但不知道如何向其传递我想要的参数。
第二次更新:
我已经取得了很大的进步!我想......我查看了示例和文档,最终将我认为应该解决这个问题的这个版本拼凑在一起:
def start_requests(self):
baseUrl = "http://www.website.com/search.aspx?keyword=#&&sort=Sorting&page="
target = 'ctl00$empcnt$ucResults$pagination'
requests = []
for i in range(1, 5):
url = baseUrl + str(i)
argument = str(i+1)
data = {'__EVENTTARGET': target, '__EVENTARGUMENT': argument}
currentPage = FormRequest(url, data)
requests.append(currentPage)
return requests
这个想法是,这就像对待表单一样对待 POST 请求并进行相应的更新。然而,当我实际尝试运行它时,我得到以下回溯(为简洁起见,精简):
2013-03-22 04:03:03-0400 [guru] ERROR: Unhandled error on engine.crawl()
dfd.addCallbacks(request.callback or spider.parse, request.errback)
File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 280, in addCallbacks
assert callable(callback)
exceptions.AssertionError:
2013-03-22 04:03:03-0400 [-] ERROR: Unhandled error in Deferred:
2013-03-22 04:03:03-0400 [-] Unhandled Error
Traceback (most recent call last):
Failure: scrapy.exceptions.IgnoreRequest: Skipped (request already seen)
改变问题以更直接地了解这篇文章已经变成了什么。
想法?
附:当第二个错误发生时,scrapy 无法完全关闭,我必须发送 SIGINT 两次才能真正结束。