使用scrapy与javascript __doPostBack方法的麻烦

时间:2013-03-22 00:39:13

标签: javascript python asp.net scrapy dopostback

尝试自动从公共搜索中获取搜索结果,但遇到了一些麻烦。 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)

更改问题更多地针对这篇文章的内容。

思想?

P.S。当第二个错误发生时,scrapy无法清除关闭,我必须发送一次SI​​GINT两次才能实际结束。

1 个答案:

答案 0 :(得分:2)

FormRequestformdata的构造函数中没有位置参数:

class FormRequest(Request):
    def __init__(self, *args, **kwargs):
        formdata = kwargs.pop('formdata', None)

所以你实际上要说formdata=

requests.append(FormRequest(url, formdata=data))