Python 不带'的爬网表数据;下一步按钮';用刮痧
我对Python 不带'的爬网表数据;下一步按钮';用刮痧,python,web-scraping,scrapy,Python,Web Scraping,Scrapy,我对Scrapy很陌生,我试图从中获取每页的表数据 这是我的代码: import scrapy class UAESpider(scrapy.Spider): name = 'uae_free' allowed_domains = ['https://www.uaeonlinedirectory.com'] start_urls = [ 'https://www.uaeonlinedirectory.com/UFZOnlineDirectory.a
Scrapy
很陌生,我试图从中获取每页的表数据
这是我的代码:
import scrapy
class UAESpider(scrapy.Spider):
name = 'uae_free'
allowed_domains = ['https://www.uaeonlinedirectory.com']
start_urls = [
'https://www.uaeonlinedirectory.com/UFZOnlineDirectory.aspx?item=A'
]
def parse(self, response):
pages = response.xpath('//table[@class="GridViewStyle"]//tr[12]')
for page in pages[1:11]:
rows = page.xpath('//table[@class="GridViewStyle"]//tr')
for row in rows[1:11]:
yield {
'company_name': row.xpath('.//td[2]//text()').get(),
'company_name_link': row.xpath('.//td[2]//a/@href').get(),
'zone': row.xpath('.//td[4]//text()').get(),
'category': row.xpath('.//td[6]//text()').get(),
'category_link': row.xpath('.//td[6]//a/@href').get()
}
next_page = response.xpath('//table[@class="GridViewStyle"]//tr[12]//td[11]//a/@href').get()
if next_page:
yield scrapy.Request(url=next_page, callback=self.parse)
但它不起作用,我得到了这个错误,下面的URL是指向第11页的链接:
ValueError: Missing scheme in request url: javascript:__doPostBack('ctl00$ContentPlaceHolder2$grdDirectory','Page$11')
你们知道怎么修复这个错误吗
更新:
按照@zmike建议的说明进行操作,这就是我目前所做的:
import scrapy
from scrapy.http import FormRequest
URL = 'https://www.uaeonlinedirectory.com/UFZOnlineDirectory.aspx?item=A'
class UAESpider(scrapy.Spider):
name = 'uae_free'
allowed_domains = ['https://www.uaeonlinedirectory.com/UFZOnlineDirectory.aspx?item=A']
start_urls = [
'https://www.uaeonlinedirectory.com/UFZOnlineDirectory.aspx?item=A'
]
def parse(self, response):
self.data = {}
for form_input in response.css('form#aspnetForm input'):
name = form_input.xpath('@name').extract()[0]
try:
value = form_input.xpath('@value').extract()[0]
except IndexError:
value = ""
self.data[name] = value
self.data['ctl00_ContentPlaceHolder2_panelGrid'] = 'ctl00$ContentPlaceHolder2$grdDirectory'
self.data['__EVENTTARGET'] = 'ctl00$ContentPlaceHolder2$grdDirectory'
self.data['__EVENTARGUMENT'] = 'Page$1'
return FormRequest(url=URL,
method='POST',
callback=self.parse_page,
formdata=self.data,
meta={'page':1},
dont_filter=True)
def parse_page(self, response):
current_page = response.meta['page'] + 1
rows = response.xpath('//table[@class="GridViewStyle"]//tr')
for row in rows[1:11]:
yield {
'company_name': row.xpath('.//td[2]//text()').get(),
'company_name_link': row.xpath('.//td[2]//a/@href').get(),
'zone': row.xpath('.//td[4]//text()').get(),
'category': row.xpath('.//td[6]//text()').get(),
'category_link': row.xpath('.//td[6]//a/@href').get()
}
return FormRequest(url=URL,
method='POST',
formdata={
'__EVENTARGUMENT': 'Page$%d' % current_page,
'__EVENTTARGET': 'ctl00$ContentPlaceHolder2$grdDirectory',
'ctl00_ContentPlaceHolder2_panelGrid':'ctl00$ContentPlaceHolder2$grdDirectory',
'':''},
meta={'page': current_page},
dont_filter=True)
这段代码只从第一个页面获取表数据,它不会移动到剩余页面。你知道我哪里做错了吗?这里是一个正在运行的(尽管很粗糙)爬虫实现,它可以遍历所有页面。一些注意事项:
- 表单数据需要不同的参数,例如
,\uuu EVENTTARGET
,\uu EVENTVALIDATION
等。\uu VIEWSTATEGENERATOR
- 我使用XPath来获取它们,而不是正则表达式
- 以下内容不是必需的:
self.data['ctl00\u contentplaceholder 2\u panelGrid']=“ctl00$contentplaceholder 2$grdDirectory”
- 为了简单起见,我组合了这些函数回调允许它在所有页面中循环
import scrapy
从scrapy.http导入FormRequest
等级UAESpider(刮毛蜘蛛):
名称='阿联酋自由'
标题={
'X-MicrosoftAjax':'Delta=true',
“用户代理”:“Mozilla/5.0(Macintosh;英特尔Mac OS X 10_10_2)AppleWebKit/537.36(KHTML,如Gecko)Chrome/41.0.2272.76 Safari/537.36”
}
允许的_域=['www.uaeonlinedirectory.com']
#TODO:包括所有其他项目的URL(例如A-Z)
起始URL=['https://www.uaeonlinedirectory.com/UFZOnlineDirectory.aspx?item=A']
当前页面=0
def解析(自我,响应):
#请求下一页
self.current\u页面=self.current\u页面+1
如果self.current_page==1:
#提交表格(第一页)
数据={}
对于response.css中的form#u input('form#aspnetForm input'):
name=form_input.xpath('@name').extract()[0]
尝试:
value=form_input.xpath('@value').extract()[0]
除索引器外:
value=“”
数据[名称]=值
数据[''事件目标']='ctl00$MainContent$List'
数据[''事件参数']='第1页'
其他:
#使用XPATH提取表单字段和参数
event\u validation=response.xpath('//input[@id=“\uu EVENTVALIDATION”]/@value”).extract()
view_state=response.xpath('//input[@id=“u VIEWSTATE”]/@value”).extract()
view\u state\u generator=response.xpath('//input[@id=“\u viewstategerator”]/@value”).extract()
view_state_encrypted=response.xpath('//input[@id=“u VIEWSTATEENCRYPTED”]/@value”).extract()
数据={
“_EVENTTARGET”:“ctl00$ContentPlaceholder 2$GRD目录”,
“\uu EVENTARGUMENT”:”第$%d页“%self.current\u页,
“事件验证”:事件验证,
“视图状态”:视图状态,
“\u视图状态生成器”:视图状态生成器,
“\u视图状态加密”:视图状态加密,
“\uu ASYNCPOST”:“true”,
'': ''
}
#公司收益率
#TODO:将其移动到其他函数
rows=response.xpath('//table[@class=“GridViewStyle”]//tr')
对于行中的行[1:11]:
结果={
“公司名称”:row.xpath(“.//td[2]//text()”).get(),
'company_name_link':row.xpath('.//td[2]//a//@href').get(),
“区域”:行.xpath('.//td[4]//text()).get(),
'category':row.xpath('.//td[6]//text()')。get(),
'category_link':row.xpath('.//td[6]//a//@href').get()
}
打印(结果)
产量结果
#TODO:检查是否有下一页,只有在有下一页时才进行屈服
yield FormRequest(url=self.start_url[0],#TODO:更改此项,使索引不被硬编码
方法='POST',
formdata=数据,
callback=self.parse,
meta={'page':self.current_page},
Don_filter=True,
headers=self.headers)
也许这会有所帮助:@zmike我会关注你的链接,在更新部分,这就是我目前所做的。但它不起作用,你知道我哪里错了吗?