需要JavaScript交互的刮擦页面

时间:2014-05-25 16:32:08

标签: python scrapy scrapy-spider

我正试图用Scrapy抓住https://a836-propertyportal.nyc.gov/Default.aspx。我在使用FormRequest时遇到了困难 - 具体来说,我不知道如何告诉Scrapy如何填充块和批量表单,然后获取页面的响应。我尝试按照此处找到的Scrapy网站上的FormRequest示例(http://doc.scrapy.org/en/latest/topics/request-response.html#using-formrequest-from-response-to-simulate-a-user-login),但仍然难以正确点击"搜索"按钮。

如果您能提供任何建议以便我可以从提交的页面中提取数据,我将非常感激。关于SO的一些海报表明,Scrapy无法很好地处理JS事件,而是使用像CasperJS这样的另一个库。

更新:如果有人可以请我指向允许我提交表单并检索后续信息的Java / Python / JS库,我将非常感激

更新代码(遵循Pawel的评论):我的代码可在此处找到:

from scrapy.spider import Spider
from scrapy.selector import Selector
from scrapy.http import FormRequest, Request

class MonshtarSpider(Spider):
name = "monshtar"
allowed_domains = ["https://a836-propertyportal.nyc.gov/Default.aspx"]
start_urls = (
    'https://a836-propertyportal.nyc.gov/Default.aspx/',
    )

def parse(self, response):
    print "entered the parsing section!!"

    yield Request("https://a836-propertyportal.nyc.gov/ExemptionDetails.aspx", 
        cookies = {"borough":"1", "block":"01000", "style":"default", "lot":"0011"}, callback = self.aftersubmit)


def aftersubmit(self, response):
    #get the data....
    print "SUCCESS!!\n\n\n"

2 个答案:

答案 0 :(得分:2)

您的页面有点古怪且难以解析,在提交有效的POST请求页面后,回复302 http状态和一堆cookie(顺便说一下,您的formdata无效,您需要在参数中用美元替换下划线)。

将GET发送到https://a836-propertyportal.nyc.gov/ExemptionDetails.aspx

后,可以查看内容

最令人惊讶的是,您可以仅使用Cookie来抓取此网站,而无需POST请求。 POST只是为了给你cookie,它不会重定向到或响应html响应。您可以从蜘蛛中操纵这些cookie。您只需要先进行GET以获取会话cookie,然后再进行连续GETS以及自治市镇,阻止等。

在scrapy shell中试试这个:

pawel@stackoverflow:~/stack/scrapy$ scrapy shell "https://a836-propertyportal.nyc.gov/Default.aspx"

In [1]: from scrapy.http import Request

In [2]: req = Request("https://a836-propertyportal.nyc.gov/ExemptionDetails.aspx", cookies = {"borough":"1", "block":"01000", "style":"default", "lot":"0011"})

In [3]: fetch(req)

In [4]: view(response)

Out[5]: True # opening browser window

此时的响应将包含给定块,行政区和批次的属性数据。现在你只需要在蜘蛛中使用这些知识。只需用GET替换你的POST与cookie,添加回调你在shell中的内容,它应该工作正常。

如果这仍然不起作用或以某种方式不适合您的目的尝试提取隐藏的ajax参数(nullctl00_ScriptManager1_HiddenField的值),将其添加到formdata(当然要更正您的formdata,以便它与浏览器发送的相同)。

答案 1 :(得分:0)

您不单击搜索按钮,而是对包含所有数据的页面发出POST请求。但是检查代码,它会发送大量数据。下面我发布了我的请求......

ctl00_ScriptManager1_HiddenField:;;AjaxControlToolkit, Version=3.0.11119.25904, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e:en-US:f48478dd-9360-4d50-94c1-5c5fa55bd379:865923e8:411fea1c:e7c87f07:91bd373d:1d58b08c:8e72a662:acd642d2:596d588c:77c58d20:14b56adc:269a19ae:bbfda34c:30a78ec5:5430d994
__EVENTTARGET:
__EVENTARGUMENT:
__VIEWSTATE:/wEPDwULLTEwMDA4NDY4ODAPZBYCZg9kFgICBQ9kFgQCAg9kFgQCAQ8WAh4HVmlzaWJsZWhkAgcPFgIfAGgWAgIBDxYCHglpbm5lcmh0bWwFGEFsZXJ0IGZvcjxiciAvPiBCQkwgOiAtLWQCBA9kFgQCAg9kFgQCAQ9kFgRmDw8WBB4IQ3NzQ2xhc3MFF2FjY29yZGlvbkhlYWRlclNlbGVjdGVkHgRfIVNCAgJkZAIBDw8WBB8CBRBhY2NvcmRpb25Db250ZW50HwMCAhYCHgVzdHlsZQUOZGlzcGxheTpibG9jaztkAgIPZBYEZg8PFgQfAgUPYWNjb3JkaW9uSGVhZGVyHwMCAmRkAgEPDxYEHwIFEGFjY29yZGlvbkNvbnRlbnQfAwICFgIfBAUNZGlzcGxheTpub25lOxYCAgEPZBYCZg9kFgZmDw9kFgIfBAUNZGlzcGxheTpub25lO2QCDA8PFgIfAGhkZAINDw8WAh8AaGRkAgMPD2QWBh4FU3R5bGUFN3dpZHRoOjM1MHB4O2JhY2tncm91bmQ6d2hpdGU7ZGlzcGxheTpub25lO29wYWNpdHk6MC45MjseC29ubW91c2VvdmVyBQ93d2hIZWxwLnNob3coKTseCm9ubW91c2VvdXQFD3d3aEhlbHAuaGlkZSgpO2Rky2sFuMlw1iy/E0GN9cB65RXg7Aw=
__EVENTVALIDATION:/wEWGgKWm9a2BgL687aTAwLmha0BAujn2IECAo3DtaEJAtLdz/kGAr3g5K4DAu78ttcEAvOB3+MGAvKB3+MGAvGB3+MGAvCB3+MGAveB3+MGAoHAg44PArT/mOoPAqrvlMAJAtzQstcEAoDswboFAoHswboFAoLswboFAoPswboFAoTswboFAtjqpO8KAujQ7b0GAqvgnb0NAsPa/KsBQz19YIqBRvCWvZh8bk6XKxp+wQo=
grpStyle:blue
ctl00$SampleContent$MyAccordion_AccordionExtender_ClientState:0
ctl00$SampleContent$ctl01$TextBox1:(unable to decode value)
ctl00$SampleContent$ctl01$ddlParclBorough:1
ctl00$SampleContent$ctl01$txtBlock:100
ctl00$SampleContent$ctl01$txtLot:200
ctl00$SampleContent$ctl01$btnSearchBBL:Please Wait...
ctl00$SampleContent$ctl03$TextBox2:(unable to decode value)
ctl00$SampleContent$ctl03$ddlParclBoroughPropAddr:1
ctl00$SampleContent$ctl03$txtHouseNbr:
ctl00$SampleContent$ctl03$txtStreetNm:
ctl00$SampleContent$ctl03$txtAptNbr:

我的建议是使用支持执行JS的剪贴簿库。或者使用别的东西。我使用Selenium和WebDriver在浏览器中执行代码获得了很多成功,它支持JS。

更新

您有一个示例How to submit a form using PhantomJS