使用隐藏链接url的__doPostBack进行刮擦
Scraping with __doPostBack with link url hidden
我正试图从使用__doPostBack
函数的网站上抓取搜索结果。网页显示每个搜索查询10个结果。要查看更多结果,必须单击触发__doPostBack
javascript的按钮。经过一些研究,我意识到POST请求的行为就像一个表单,可以简单地使用scrapy的FormRequest
来填充该表单
javascript __doPostBack方法使用scrapy时出现问题
编写以下脚本。
# -*- coding: utf-8 -*-
from scrapy.contrib.spiders import CrawlSpider
from scrapy.http import FormRequest
from scrapy.http import Request
from scrapy.selector import Selector
from ahram.items import AhramItem
import re
class MySpider(CrawlSpider):
name = u"el_ahram2"
def start_requests(self):
search_term = u'اقتصاد'
baseUrl = u'http://digital.ahram.org.eg/sresult.aspx?srch=' + search_term + u'&archid=1'
requests = []
for i in range(1, 4):#crawl first 3 pages as a test
argument = u"'Page$"+ str(i+1) + u"'"
data = {'__EVENTTARGET': u"'GridView1'", '__EVENTARGUMENT': argument}
currentPage = FormRequest(baseUrl, formdata = data, callback = self.fetch_articles)
requests.append(currentPage)
return requests
def fetch_articles(self, response):
sel = Selector(response)
for ref in sel.xpath("//a[contains(@href,'checkpart.aspx?Serial=')]/@href").extract():
yield Request('http://digital.ahram.org.eg/' + ref, callback=self.parse_items)
def parse_items(self, response):
sel = Selector(response)
the_title = ' '.join(sel.xpath("//title/text()").extract()).replace(''n','').replace(''r','').replace(''t','')#* mean 'anything'
the_authors = '---'.join(sel.xpath("//*[contains(@id,'editorsdatalst_HyperLink')]//text()").extract())
the_text = ' '.join(sel.xpath("//span[@id='TextBox2']/text()").extract())
the_month_year = ' '.join(sel.xpath("string(//span[@id = 'Label1'])").extract())
the_day = ' '.join(sel.xpath("string(//span[@id = 'Label2'])").extract())
item = AhramItem()
item["Authors"] = the_authors
item["Title"] = the_title
item["MonthYear"] = the_month_year
item["Day"] = the_day
item['Text'] = the_text
return item
我现在的问题是"fetch_articles"从未被调用:
2014-05-27 12:19:12+0200 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
2014-05-27 12:19:13+0200 [el_ahram2] DEBUG: Crawled (200) <POST http://digital.ahram.org.eg/sresult.aspx?srch=%D8%A7%D9%82%D8%AA%D8%B5%D8%A7%D8%AF&archid=1> (referer: None)
2014-05-27 12:19:13+0200 [el_ahram2] DEBUG: Crawled (200) <POST http://digital.ahram.org.eg/sresult.aspx?srch=%D8%A7%D9%82%D8%AA%D8%B5%D8%A7%D8%AF&archid=1> (referer: None)
2014-05-27 12:19:13+0200 [el_ahram2] DEBUG: Crawled (200) <POST http://digital.ahram.org.eg/sresult.aspx?srch=%D8%A7%D9%82%D8%AA%D8%B5%D8%A7%D8%AF&archid=1> (referer: None)
2014-05-27 12:19:13+0200 [el_ahram2] INFO: Closing spider (finished)
找了几天之后,我觉得自己完全被卡住了。我是python的初学者,所以这个错误可能很小。然而,如果不是这样,这个线程可能对许多人有用。提前感谢您的帮助。
您的代码很好。fetch_articles
正在运行。您可以通过添加打印语句来测试它。
但是,网站要求您验证POST请求。为了验证它们,您的请求主体中必须有__EVENTVALIDATION
和__VIEWSTATE
,以证明您对它们的表单做出了响应。为了获得这些字段,您需要首先发出get请求,并从表单中提取这些字段。如果不提供这些字段,则会得到一个错误页面,该页面不包含任何带有"checkpart.aspx?Serial="的链接,因此您的for
循环没有被执行。
以下是我如何设置start_request
,然后fetch_search
执行start_request
以前的操作。
class MySpider(CrawlSpider):
name = u"el_ahram2"
def start_requests(self):
search_term = u'اقتصاد'
baseUrl = u'http://digital.ahram.org.eg/sresult.aspx?srch=' + search_term + u'&archid=1'
SearchPage = Request(baseUrl, callback = self.fetch_search)
return [SearchPage]
def fetch_search(self, response):
sel = Selector(response)
search_term = u'اقتصاد'
baseUrl = u'http://digital.ahram.org.eg/sresult.aspx?srch=' + search_term + u'&archid=1'
viewstate = sel.xpath("//input[@id='__VIEWSTATE']/@value").extract().pop()
eventvalidation = sel.xpath("//input[@id='__EVENTVALIDATION']/@value").extract().pop()
for i in range(1, 4):#crawl first 3 pages as a test
argument = u"'Page$"+ str(i+1) + u"'"
data = {'__EVENTTARGET': u"'GridView1'", '__EVENTARGUMENT': argument, '__VIEWSTATE': viewstate, '__EVENTVALIDATION': eventvalidation}
currentPage = FormRequest(baseUrl, formdata = data, callback = self.fetch_articles)
yield currentPage
...
def fetch_articles(self, response):
sel = Selector(response)
print response._get_body() # you can write to file and do an grep
for ref in sel.xpath("//a[contains(@href,'checkpart.aspx?Serial=')]/@href").extract():
yield Request('http://digital.ahram.org.eg/' + ref, callback=self.parse_items)
我找不到您正在搜索的"checkpart.aspx?Serial="。
这可能无法解决您的问题,但使用answer而不是注释来设置代码格式。
相关文章:
- 在单击任何位置时隐藏元素,而不检查每次DOM单击
- 显示5秒后隐藏潜水
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 剑道UI内联编辑:如何在点击其他按钮时隐藏按钮
- 浮动页脚栏-使用Bootstrap隐藏
- 在jquery中为显示/隐藏设置cookie
- 单击按钮后如何逐个调用分区,上一个分区将隐藏
- 从var向代码隐藏函数传递值
- Image赢得't隐藏在滚动jQuery上
- 具有rowGrouping的数据表无法隐藏列
- Jquery隐藏未触发
- JavaScript 检查隐藏字段中的值并将其设置为隐藏字段值
- 分部隐藏在jquery中不起作用
- 点击后隐藏潜水?(但如果Div是一面旗帜呢?)
- javascript.点击隐藏事件故障
- 禁用(而不是隐藏)浏览器滚动条
- PHP Javascript显示/隐藏按钮不工作
- 在mvc应用程序中,在回发时保留最初隐藏的文本框的隐藏或可见状态
- 如何通过溢出来判断元素被切断了多少像素:隐藏在父级上
- ng隐藏和ng显示无法正常工作