【问题标题】:Scrapy Callback Function not scraping the Entire Data?Scrapy 回调函数不抓取整个数据?
【发布时间】:2015-07-13 04:24:11
【问题描述】:

首先这是我的代码-:

from twisted.internet import reactor
from scrapy.crawler import CrawlerProcess, CrawlerRunner
import scrapy
#from scrapy import log, signals
from scrapy.utils.log import configure_logging
from scrapy.utils.project import get_project_settings
from scrapy.settings import Settings
import datetime
from multiprocessing import Process, Queue
import os
from scrapy.http import Request
from scrapy import signals
from scrapy.xlib.pydispatch import dispatcher
from scrapy.signalmanager import SignalManager
import re

#query=raw_input("Enter a product to search for= ")
query='apple'
query1=query.replace(" ", "+")  


class DmozItem(scrapy.Item):

    productname = scrapy.Field()
    product_link = scrapy.Field()
    current_price = scrapy.Field()
    mrp = scrapy.Field()
    offer = scrapy.Field()
    imageurl = scrapy.Field()
    outofstock_status = scrapy.Field()
    add = scrapy.Field()

class DmozSpider(scrapy.Spider):
    name = "dmoz"
    allowed_domains = ["http://www.bestmercato.com"]


    def start_requests(self):

        task_urls = [
        ]
        i=1
        for i in range(1,2):
            temp=("https://www.bestmercato.com/index.php?route=product/search&search="+query1+"&page="+str(i))
            task_urls.append(temp)
            i=i+1

        start_urls = (task_urls)
#       p=len(task_urls)
        return [ Request(url = start_url) for start_url in start_urls ]


    def parse(self, response):
        items = []

        for sel in response.xpath('//html/body/div/div/div[4]/div/div/div[5]/div'):

            item = DmozItem()

            item['productname'] = str(sel.xpath('div[@class="product-thumb"]/div[@class="small_detail"]/div[@class="name"]/a/text()').extract())[3:-2]

            item['product_link'] = str(sel.xpath('div[@class="product-thumb"]/div[@class="small_detail"]/div[@class="name"]/a/@href').extract())[3:-2]

            point1 = sel.xpath('div[@class="product-thumb"]/div[@class="small_detail"]/div[4]').extract()
            point = str(sel.xpath('div[@class="product-thumb"]/div[@class="small_detail"]/div[4]/@class').extract())[3:-2]
            checker = "options" in point
            item['current_price'] = ""
            if checker:
                i=1
                p=1
                while i==1:
                    t = str(sel.xpath('div[@class="product-thumb"]/div[@class="small_detail"]/div[4]/div/select/option['+str(p)+']/text()').extract())[3:-2]
                    #print t        
                    if 'Rs' not in t:
                        i = 2
                    elif 'Rs' in t:
                        i = 1
                    t= " ".join(t)
                    s = t.translate(None, '\ t')[:-2]
                    item['current_price'] = item['current_price'] + ' ; ' + s
                    p = p+1
                item['current_price'] = item['current_price'][3:-3]

            else:
                item['current_price'] = 'Rs. ' + str(sel.xpath('div[@class="product-thumb"]/div[@class="small_detail"]/div[not (@class="name") or not(@class="description") or not(@class="qty") or not(@class="box_btn_icon")]/text()').extract())[46:-169]
                re.findall(r"[-+]?\d*\.\d+|\d+", item["current_price"])

            try:
                test1 = str(sel.xpath('div/div[2]/div[3]/span[1]/text()').extract())[3:-2]
                _digits = re.compile('\d')
                if bool(_digits.search(test1)):
                    print 'hi'
                    test1=test1[:2]+'. '+test1[3:]
                    item['mrp'] = test1
                    #item['mrp'][2:2]='.'
                    test2 = str(sel.xpath('div/div[2]/div[3]/span[2]/text()').extract())[3:-2]
                    test2=test2[:2]+'. '+test2[3:]
                    item['current_price']=test2

                else:
                    item['mrp'] = item['current_price']                 
            except:
                item['mrp'] = item['current_price']

            item['offer'] = 'No additional offer available'

            item['imageurl'] = str(sel.xpath('div[@class="product-thumb"]/div[@class="image"]/a[not (@class="sft_quickshop_icon")]/img[@class="img-responsive"]/@src').extract())[3:-2]

            item['outofstock_status'] = str('In Stock')

            request = Request(str(item['product_link']),callback=self.parse2, dont_filter=True)
            request.meta['item'] = item
#           print item
            items.append(item)
            return request

        print (items)

    def parse2(self, response):

        item = response.meta['item']
        item['add'] = response.url
        return item

spider1 = DmozSpider()
settings = Settings()
settings.set("PROJECT", "dmoz")
settings.set("CONCURRENT_REQUESTS" , 100)
#)
#settings.set( "DEPTH_PRIORITY" , 1)
#settings.set("SCHEDULER_DISK_QUEUE" , "scrapy.squeues.PickleFifoDiskQueue")
#settings.set( "SCHEDULER_MEMORY_QUEUE" , "scrapy.squeues.FifoMemoryQueue")
crawler = CrawlerProcess(settings)
crawler.crawl(spider1)
crawler.start()

现在,这些是我面临的问题。

1. 可以使用此 xpath 找到许多 div - '//html/body/div/div/div[4]/div/div/div[5]/div ' .但是,上面的代码仅抓取第一个 div 的内容,即具有 xpath 'html/body/div/div/div[4]/div/div/div[5]/div[1]' ,而不是全部。

在我评论这三行的那一刻,刮板刮掉了所有东西,显然我无法在项目中添加“添加”字段-:

request = Request(str(item['product_link']),callback=self.parse2, dont_filter=True)
request.meta['item'] = item
return request

所以,除了我的项目类中的“添加”字段(注意 DmozItem 类)之外,我还想抓取所有 div。我怎么做?请为我的具体案例提供更正的代码,这样最好!

2.其次,正如我所说,当我评论上面提到的三行代码时,程序会在接近 5 秒(大约 4.9 秒)的时间内抓取所有内容。 p>

但是一旦我取消注释,那 3 行(同样是我上面提到的那些),程序的运行时间就会大大超过,它的运行时间接近 9 秒(大约 8.8 - 8.9 秒)。为什么会这样?是不是因为这个 - dont_filter=True?请提出解决这个问题的方法,因为运行时对我来说是一个非常大的问题。另外,我可以以某种方式减少 5 秒(大约 4.9 秒)的初始时间吗?

【问题讨论】:

    标签: python callback web-scraping scrapy scrapy-spider


    【解决方案1】:

    使用html/body/div/div/div[4]/div/div/div[5]//div 获取div[5] 之后的所有divs。

    编辑: 这是正确的 xpath - //html/body/div/div/div[4]/div/div/div[5]/div,它在 div[5] 之后给出了所有 div。前面提到的,给出了多个错误!

    如果您在循环内执行return 语句,您将结束整个方法执行。因此,如果您启用这三行,您将在第一个元素之后结束您的方法(以及 for 循环)的执行。

    这意味着你应该yield你的请求而不是returning它。

    【讨论】:

    • 实际上,您的回答确实为我解决了问题。但是发生的问题是,我的程序首先在主 parse() 函数中提取所有产品的数据并打印它们,然后将其全部打印出来。之后,它在函数 parse2() 中一一进行,然后显示它们。但随着它一个接一个地进行,程序停顿了很多。 :( 。这导致运行时间大幅增加。:( 运行时间增加到 39 秒。我该如何克服?这对我来说是一个大问题。:( 所以,请帮助我那个。:)
    • 我可以减少正在发生的巨大运行时间吗?请有人帮忙。这是一个值得关注的问题。请帮忙。 @GHajba 或其他任何人也可以提供帮助!
    • 好吧,因为你 yield 新请求 Scrapy 有额外的工作要做。我不知道您正在解析多少个站点,但如果有很多站点,即使启用了缓存,它也会影响抓取工具的性能。您还可以使用其他一些性能调优方法来加快应用程序的整体性能,而不仅仅是这一部分。
    • 哦.. 是否有一些材料可用于在线某处的这些性能调整方法?或者您能否简要介绍一下它们。这是我抓取的一个网站。我打算刮掉其中大约 40 个,然后从一个脚本中运行它们。那么,这会导致一个巨大的问题,对吧?所以,如果你能详细说明一下scrapy的性能调整方法,那对我来说是最好的!非常感谢!请回复! :) 这对我来说是一个非常大的问题,这就是原因! :(
    • 您几乎可以在 StackOverflow 上找到所有答案;)stackoverflow.com/a/17030686/3941341
    猜你喜欢
    • 2017-09-04
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 2013-05-23
    • 2013-10-02
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多