Xpath Scrapy-从表中提取项目
试着让我的头绕着痒痒,但碰到了一些死胡同 我在一个页面上有两个表,我想从每个表中提取数据,然后移动到下一个页面 表看起来像这样(第一个称为Y1,第二个称为Y2),结构相同Xpath Scrapy-从表中提取项目,xpath,scrapy,Xpath,Scrapy,试着让我的头绕着痒痒,但碰到了一些死胡同 我在一个页面上有两个表,我想从每个表中提取数据,然后移动到下一个页面 表看起来像这样(第一个称为Y1,第二个称为Y2),结构相同 <div id="Y1" style="margin-bottom: 0px; margin-top: 15px;"> <h2>First information</h2><hr style="margin-top: 5p
<div id="Y1" style="margin-bottom: 0px; margin-top: 15px;">
<h2>First information</h2><hr style="margin-top: 5px; margin-bottom: 10px;">
<table class="table table-striped table-hover table-curved">
<thead>
<tr>
<th class="tCol1" style="padding: 10px;">First Col Head</th>
<th class="tCol2" style="padding: 10px;">Second Col Head</th>
<th class="tCol3" style="padding: 10px;">Third Col Head</th>
</tr>
</thead>
<tbody>
<tr>
<td>Info 1</td>
<td>Monday 5 September, 2016</td>
<td>Friday 21 October, 2016</td>
</tr>
<tr class="vevent">
<td class="summary"><b>Info 2</b></td>
<td class="dtstart" timestamp="1477094400"><b></b></td>
<td class="dtend" timestamp="1477785600">
<b>Sunday 30 October, 2016</b></td>
</tr>
<tr>
<td>Info 3</td>
<td>Monday 31 October, 2016</td>
<td>Tuesday 20 December, 2016</td>
</tr>
<tr class="vevent">
<td class="summary"><b>Info 4</b></td>
<td class="dtstart" timestamp="1482278400"><b>Wednesday 21 December, 2016</b></td>
<td class="dtend" timestamp="1483315200">
<b>Monday 2 January, 2017</b></td>
</tr>
</tbody>
</table>
这里没有错误,但它只是返回了大量有关爬网的信息,但没有实际结果
更新:
import scrapy
class SchoolSpider(scrapy.Spider):
name = "school"
allowed_domains = ["termdates.co.uk"]
start_urls = (
'https://termdates.co.uk/school-holidays-16-19-abingdon/',
)
def parse_products(self, response):
products = sel.xpath('//*[@id="Year1"]/table//tr')
for p in products[1:]:
item = dict()
item['hol'] = p.xpath('td[1]/text()').extract_first()
item['first'] = p.xpath('td[1]/text()').extract_first()
item['last'] = p.xpath('td[1]/text()').extract_first()
yield item
这给了我:缩进错误:意外缩进
如果我运行下面的修改脚本(感谢@Granitosaurus)以输出到CSV(-o schoolDates.CSV),我会得到一个空文件:
import scrapy
class SchoolSpider(scrapy.Spider):
name = "school"
allowed_domains = ["termdates.co.uk"]
start_urls = ('https://termdates.co.uk/school-holidays-16-19-abingdon/',)
def parse_products(self, response):
products = sel.xpath('//*[@id="Year1"]/table//tr')
for p in products[1:]:
item = dict()
item['hol'] = p.xpath('td[1]/text()').extract_first()
item['first'] = p.xpath('td[1]/text()').extract_first()
item['last'] = p.xpath('td[1]/text()').extract_first()
yield item
这是日志:
- 2017-03-23 12:04:08[刮屑芯发动机]信息:十字轴已打开 2017-03-23 12:04:08[scrapy.extensions.logstats]信息:已爬网0 页数(以0页/分钟的速度),刮取0项(以0项/分钟的速度)2017-03-23 12:04:08[scrapy.extensions.telnet]调试:telnet控制台侦听 在…上2017-03-23 12:04:08[刮屑核心引擎]调试:爬网(200) https://termdates.co.uk/robots.txt>(推荐人:无)2017-03-23 12:04:08[scrapy.core.engine]调试:已爬网(200)https://termdates.co.uk/school-holidays-16-19-abingdon/>(参考: 无)2017-03-23 12:04:08[scrapy.core.scraper]错误:十字轴错误 处理https://termdates.co.uk/school-holidays-16-19-abingdon/>(参考: 无)回溯(最近一次呼叫最后一次):文件 “c:\python27\lib\site packages\twisted\internet\defer.py”,第653行, 运行中回调 current.result=callback(current.result,*args,**kw)文件“c:\python27\lib\site packages\scrapy-1.3.3-py2.7.egg\scrapy\spider\uuuuu init\uuuuu.py”, 第76行,在语法分析中 升起未执行错误未执行错误2017-03-23 12:04:08[刮屑.堆芯.发动机]信息:关闭卡盘(完成)2017-03-23 12:04:08[scrapy.statscollectors]信息:转储scrapy统计信息: {'downloader/request_bytes':467,'downloader/request_count':2, “下载器/请求\方法\计数/获取”:2, “下载/响应字节”:11311,“下载/响应计数”:2, “下载/响应\状态\计数/200”:2,“完成\原因”: “完成”、“完成时间”:datetime.datetime(2017,3,23,12,4,8, 845000),“日志计数/调试”:3,“日志计数/错误”:1, “日志计数/信息”:7,“响应计数”:2, “调度程序/出列”:1,“调度程序/出列/内存”:1, “调度程序/排队”:1,“调度程序/排队/内存”:1, “蜘蛛异常/未实现错误”:1,“开始时间”: datetime.datetime(2017,3,23,12,4,8356000)}2017-03-23 12:04:08 [scrapy.core.engine]信息:十字轴关闭(完成)
import scrapy
class SchoolSpider(scrapy.Spider):
name = "school"
allowed_domains = ["termdates.co.uk"]
start_urls = ('https://termdates.co.uk/school-holidays-16-19-abingdon/',)
def parse(self, response):
products = response.xpath('//*[@id="Year1"]/table//tr')
for p in products[1:]:
item = dict()
item['hol'] = p.xpath('td[1]/text()').extract_first()
item['first'] = p.xpath('td[2]/text()').extract_first()
item['last'] = p.xpath('td[3]/text()').extract_first()
yield item
解决方案:多亏了@strong>vold
这将爬网start_URL中的所有页面,并处理不一致的表布局
# -*- coding: utf-8 -*-
import scrapy
from SchoolDates_1.items import Schooldates1Item
class SchoolSpider(scrapy.Spider):
name = "school"
allowed_domains = ["termdates.co.uk"]
start_urls = ('https://termdates.co.uk/school-holidays-16-19-abingdon/',
'https://termdates.co.uk/school-holidays-3-dimensions',)
def parse(self, response):
products = response.xpath('//*[@id="Year1"]/table//tr')
# ignore the table header row
for product in products[1:]:
item = Schooldates1Item()
item['hol'] = product.xpath('td[1]//text()').extract_first()
item['first'] = product.xpath('td[2]//text()').extract_first()
item['last'] = ''.join(product.xpath('td[3]//text()').extract()).strip()
item['url'] = response.url
yield item
您需要稍微更正代码。由于已经选择了表中的所有元素,因此无需再次指向表。因此,您可以将xpath缩短为如下内容
td[1]//text()
编辑了我的答案,因为@stutray提供了指向站点的链接。我使用这些XPath获得了您提供的html源代码:
products = sel.xpath('//*[@id="Y1"]/table//tr')
for p in products[1:]:
item = dict()
item['hol'] = p.xpath('td[1]/text()').extract_first()
item['first'] = p.xpath('td[1]/text()').extract_first()
item['last'] = p.xpath('td[1]/text()').extract_first()
yield item
上面假设每个表行包含1项。您可以使用CSS选择器而不是XPath,我总是觉得CSS选择器很简单
def parse_products(self, response):
for table in response.css("#Y1 table")[1:]:
item = Schooldates1Item()
item['hol'] = product.css('td:nth-child(1)::text').extract_first()
item['first'] = product.css('td:nth-child(2)::text').extract_first()
item['last'] = product.css('td:nth-child(3)::text').extract_first()
yield item
也不要在选择器中使用t正文
标记
Firefox尤其以向表中添加元素而闻名。另一方面,Scrapy不会修改原始页面HTML,因此如果在XPath表达式中使用,则无法提取任何数据
请提供更多信息:您尝试了什么?什么代码?哪个XPATH表达式让您感到困惑?你有没有读过关于这个问题的教程?嗨,埃尔顿,我已经在上面添加了我的最新代码。谢谢。你能提供你想要解析的站点的链接吗?另外,请尝试在xpath表达式中不使用
tbody
。@vold不使用tbody的原因是什么?这似乎是避免分析标题行的一种明显方法。@stutray tbody是由Mozilla和Chrome等浏览器添加的,它不存在于原始HTML源代码中。/
在这里不是必需的,因为表达式已绑定到第一级。如果要查找任何后代,实际上需要使用/
。另外,extract_first()
是相对较新的extract(),所以您的xpath不起作用。@Umair在OP的代码上下文中它会起作用:P。您还暗示OP不使用浏览器或某些渲染来下载源代码。因此,在这个问题的背景下,我的原始答案是可行的,但还是调整了answet以反映您的观点。谢谢各位的意见。请查看我的编辑,我正在尝试快速提问-为什么每个xpath都是td[1]
-是否td
s被删除。extract_first()
使用css或xpath没有区别,在这种情况下xpath更直接,例如td[1]
products = sel.xpath('//*[@id="Y1"]/table//tr')
for p in products[1:]:
item = dict()
item['hol'] = p.xpath('td[1]/text()').extract_first()
item['first'] = p.xpath('td[1]/text()').extract_first()
item['last'] = p.xpath('td[1]/text()').extract_first()
yield item
def parse_products(self, response):
for table in response.css("#Y1 table")[1:]:
item = Schooldates1Item()
item['hol'] = product.css('td:nth-child(1)::text').extract_first()
item['first'] = product.css('td:nth-child(2)::text').extract_first()
item['last'] = product.css('td:nth-child(3)::text').extract_first()
yield item