Scrapy爬取下来的数据不全,为什么总会有遗漏?

PaleSpring 2017-06-29 01:48:30
本人小白一枚,刚接触Scrapy框架没多久,写了一个简单的Spider,但是发现每一次爬取后的结果都比网页上的真实数据量要少,比如网站上一共有100条,但我爬下来的结果一般会少几条至几十条不等,很少有100条齐的时候。

整个爬虫有两部分,一部分是页面的横向爬取(进入下一页),另一个是纵向的爬取(进入页面中每一产品的详细页面)。之前我一直以为是pipelines存储到excel的时候数据丢失了,后来经过Debug调试,发现是在Spider中,数据就遗漏了,def parse函数中的item数量是齐的,包括yield Request加入到队列中,但是调用def parse_item函数时,就有些产品的详细页面无法进入。这是什么原因呢,是因为Scrapy异步加载受网速之类的影响么,本身就无法避免,还是说是我设计上面的问题?有什么解决的方法么,不然数据量一大那丢失的不是就很严重么。

求帮助,谢谢各位了。

以下是我的Spider的代码


import scrapy
from scrapy.http import Request
from scrapy.selector import Selector
from scrapy.spider import Spider
from CyFirst.items import CyfirstItem


class MyFirstSpider(Spider):
name = "MyFirstSpider"
allowed_doamins = ["e-shenhua.com"]
start_urls = ["https://www.e-shenhua.com/ec/auction/oilAuctionList.jsp?_DARGS=/ec/auction/oilAuctionList.jsp"]
url = 'https://www.e-shenhua.com/ec/auction/oilAuctionList.jsp'

def parse(self, response):

items = []
selector = Selector(response)
contents = selector.xpath('//table[@class="table expandable table-striped"]/tbody/tr')
urldomain = 'https://www.e-shenhua.com'

for content in contents:
item = CyfirstItem()
productId = content.xpath('td/a/text()').extract()[0].strip()
productUrl = content.xpath('td/a/@href').extract()[0]
totalUrl = urldomain + productUrl
productName = content.xpath('td/a/text()').extract()[1].strip()
deliveryArea = content.xpath('td/text()').extract()[-5].strip()
saleUnit = content.xpath('td/text()').extract()[-4]

item['productId'] = productId
item['totalUrl'] = totalUrl
item['productName'] = productName
item['deliveryArea'] = deliveryArea
item['saleUnit'] = saleUnit

items.append(item)

print(len(items))

# **************进入每个产品的子网页
for item in items:
yield Request(item['totalUrl'],meta={'item':item},callback=self.parse_item)
# print(item['productId'])

# 下一页的跳转
nowpage = selector.xpath('//div[@class="pagination pagination-small"]/ul/li[@class="active"]/a/text()').extract()[0]
nextpage = int(nowpage) + 1
str_nextpage = str(nextpage)
nextLink = selector.xpath('//div[@class="pagination pagination-small"]/ul/li[last()]/a/@onclick').extract()
if (len(nextLink)):
yield scrapy.FormRequest.from_response(response,
formdata={
#此处代码省略
},
callback = self.parse
)


# 产品子网页内容的抓取
def parse_item(self,response):
sel = Selector(response)
item = response.meta['item']

productInfo = sel.xpath('//div[@id="content-products-info"]/table/tbody/tr')
titalBidQty = ''.join(productInfo.xpath('td[3]/text()').extract()).strip()
titalBidUnit = ''.join(productInfo.xpath('td[3]/span/text()').extract())
titalBid = titalBidQty + " " +titalBidUnit
minBuyQty = ''.join(productInfo.xpath('td[4]/text()').extract()).strip()
minBuyUnit = ''.join(productInfo.xpath('td[4]/span/text()').extract())
minBuy = minBuyQty + " " + minBuyUnit

isminVarUnit = ''.join(sel.xpath('//div[@id="content-products-info"]/table/thead/tr/th[5]/text()').extract())
if(isminVarUnit == '最小变量单位'):
minVarUnitsl = ''.join(productInfo.xpath('td[5]/text()').extract()).strip()
minVarUnitdw = ''.join(productInfo.xpath('td[5]/span/text()').extract())
minVarUnit = minVarUnitsl + " " + minVarUnitdw
startPrice = ''.join(productInfo.xpath('td[6]/text()').extract()).strip().rstrip('/')
minAddUnit = ''.join(productInfo.xpath('td[7]/text()').extract()).strip()
else:
minVarUnit = ''
startPrice = ''.join(productInfo.xpath('td[5]/text()').extract()).strip().rstrip('/')
minAddUnit = ''.join(productInfo.xpath('td[6]/text()').extract()).strip()

item['titalBid'] = titalBid
item['minBuyQty'] = minBuy
item['minVarUnit'] = minVarUnit
item['startPrice'] = startPrice
item['minAddUnit'] = minAddUnit
return item
...全文
7214 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
头铁娃娃 2021-02-19
  • 打赏
  • 举报
回复
DOWNLOAD_DELAY=10试试
lkangkang 2018-02-28
  • 打赏
  • 举报
回复
你好,加上AUTOTHROTTLE_ENABLED = True还是遗漏,还需要设置别的吗?
weixin_41098640 2018-01-27
  • 打赏
  • 举报
回复
可以用scrapy-redis,用于记录请求的指纹,不会丢请求。我试过降低下载频次仍然会丢请求。后来加上了scrapy-redis,完美解决问题
sherlock_yf 2017-09-17
  • 打赏
  • 举报
回复 1
楼上的问题,我最近也遇到过了。单个页面的爬取是没有问题的,一旦超过5页后面的数据就会有丢失。总体上爬虫的逻辑是没有问题的,问题在于对方服务器的响应,也就是你的爬虫的请求速度。一旦请求速度和下载页面速度过快,就会导致服务器无数据返回,查看控制台可以看到虽然请求参数是200,但数据为空。所以,问题是没有设置爬虫的请求速度和下载速度,在setting中设置一下即可。
duhe2665991640 2017-09-11
  • 打赏
  • 举报
回复
如果downloader/request_count的数量就是缺少的呢?对一个有34页的网站,我单页爬取每次都没有问题,但是一旦5页以上一起爬取,就出现遗漏。借楼主的宝地求助路过的各位大神!
Jack-Cui 2017-06-30
  • 打赏
  • 举报
回复
打印每个存储的item信息,看看是不是有漏掉的连接,如果没有。在yield调用的函数里打印接收的response.url信息,看看接收的url是否正确。如果这些没有问题,加个延时看看,是不是因为爬取太快了。
屎克螂 2017-06-30
  • 打赏
  • 举报
回复
自已细心找原因,减少代码 多打印
Jack-Cui 2017-06-30
  • 打赏
  • 举报
回复
引用 3 楼 sinat_34659321 的回复:
引用 2 楼 c406495762 的回复:
打印每个存储的item信息,看看是不是有漏掉的连接,如果没有。在yield调用的函数里打印接收的response.url信息,看看接收的url是否正确。如果这些没有问题,加个延时看看,是不是因为爬取太快了。
谢谢你哈。是这样的,进入每一个item的详细页面前item数量是齐的,没有缺少,之前我已经找到了问题出在部分item的url没有进去,按我的理解,也就是说Scrapy的队列中有些url没有加载下去。后来我又看了下每次运行完之后的Dumping Scrapy stats,发现downloader/request_count对应的数量是正确的,然后下面downloader/response_count的数量总是缺少,问题就是在这。后来无意间的在stackoverflow查别的问题时,看到有一篇提到了settings里面的AUTOTHROTTLE_ENABLED = True这个参数,我去看了下API,然后把注释去掉,运行了几次,还真没漏了。
能解决就好,哈哈
PaleSpring 2017-06-30
  • 打赏
  • 举报
回复
引用 1 楼 uiuiy1 的回复:
自已细心找原因,减少代码 多打印
嗯嗯,解决了。谢谢
PaleSpring 2017-06-30
  • 打赏
  • 举报
回复
引用 2 楼 c406495762 的回复:
打印每个存储的item信息,看看是不是有漏掉的连接,如果没有。在yield调用的函数里打印接收的response.url信息,看看接收的url是否正确。如果这些没有问题,加个延时看看,是不是因为爬取太快了。
谢谢你哈。是这样的,进入每一个item的详细页面前item数量是齐的,没有缺少,之前我已经找到了问题出在部分item的url没有进去,按我的理解,也就是说Scrapy的队列中有些url没有加载下去。后来我又看了下每次运行完之后的Dumping Scrapy stats,发现downloader/request_count对应的数量是正确的,然后下面downloader/response_count的数量总是缺少,问题就是在这。后来无意间的在stackoverflow查别的问题时,看到有一篇提到了settings里面的AUTOTHROTTLE_ENABLED = True这个参数,我去看了下API,然后把注释去掉,运行了几次,还真没漏了。

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧