Scrapy不提取数据

时间:2017-11-09 12:57:27

标签: web-scraping scrapy scrapy-spider

我正试图从this page

获得有关汽车的一些技术信息

这是我目前的代码:

import scrapy
import re
from arabamcom.items import ArabamcomItem
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor

class BasicSpider(CrawlSpider):
    name="arabamcom"
    allowed_domains=["arabam.com"]
    start_urls=['https://www.arabam.com/ikinci-el/otomobil']

    rules=(Rule(LinkExtractor(allow=(r'/ilan')),callback="parse_item",follow=True),)

    def parse_item(self,response):
        item=ArabamcomItem()
        item['fiyat']=response.css('span.color-red.font-huge.bold::text').extract()
        item['marka']=response.css('p.color-black.bold.word-break.mb4::text').extract()
        item['yil']=response.xpath('//*[@id="js-hook-appendable-technicalPropertiesWrapper"]/div[2]/dl[1]/dd/span/text()').extract()

这是我的items.py文件

import scrapy
class ArabamcomItem(scrapy.Item):
    fiyat=scrapy.Field()
    marka=scrapy.Field()
    yil=scrapy.Field()

当我运行代码时,我可以从'marka'和'fiyat'项中获取数据,但是蜘蛛没有获得'yil'属性的任何内容。还有其他部分,如'Yakit Tipi','Vites Tipi'等。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

出了什么问题:

<强> //*[@id="js-hook-appendable-technicalPropertiesWrapper"]/......

  • 此ID以js开头,可能是动态元素由javascript追加
  • Scrapy默认无法呈现javascript。

您可以尝试两种解决方案

  • Scrapy溅

      

    这是scrapy的javascript渲染引擎

    • Install Splash as a Docker container
    • 修改您的settings.py文件以集成splash(将以下中间件附加到您的项目中)     SPLASH_URL ='http://127.0.0.1:8050'

      SPIDER_MIDDLEWARES = {
          'scrapy_splash.SplashDeduplicateArgsMiddleware':100,
      }
      
      DOWNLOADER_MIDDLEWARES = {
          'scrapy_splash.SplashCookiesMiddleware':723,
          'scrapy_splash.SplashMiddleware': 725,
          'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
      }
      
    • Request功能替换为SplashRequest

      from scrapy_splash import SplashRequest as SP
      SP(url=url, callback=parse, endpoint='render.html', args={'wait': 5})
      
  • Selenium WebDriver

      

    这是一个浏览器自动化测试框架

    • 从PyPi安装Selenium并在那里安装相应的驱动程序(例如Firefox - &gt; Geckodriver)到PATH文件夹
    • 将以下中间件类附加到项目的middleware.py文件中:

      class SeleniumMiddleware(object):
      
      @classmethod
      def from_crawler(cls, crawler):
          middleware = cls()
          crawler.signals.connect(middleware.spider_opened, signals.spider_opened)
          crawler.signals.connect(middleware.spider_closed, signals.spider_closed)
          return middleware
      
      def process_request(self, request, spider):
          request.meta['driver'] = self.driver
          self.driver.get(request.url)
          self.driver.implicitly_wait(2)
      
          body = to_bytes(self.driver.page_source)
      
          return HtmlResponse(self.driver.current_url, body=body, encoding='utf-8', request=request)
      
      def spider_opened(self, spider):
           """Change your browser mode here"""
          self.driver = webdriver.Firefox()
      
      
      def spider_closed(self, spider):
          self.driver.close()
      
    • 修改您的settings.py文件以集成Selenium中间件(将中间件附加到您的项目并将yourproject替换为您的项目名称)

      DOWNLOADER_MIDDLEWARES = {
          'yourproject.middlewares.SeleniumMiddleware': 200
      }
      

比较

  • Scrapy溅

    • Scrapy Company的官方模块
    • 您可以将启动实例部署到云端,这样您就可以浏览云中的网址,然后将render.html转移回您的蜘蛛
    • 这很慢
    • 如果存在内存泄漏,Splash容器将停止。 (确保在高内存云实例上部署splash实例)
  • Selenium网络驱动程序

    • 除非您使用PhantomJS,否则必须在您的计算机上安装带有相应自动测试驱动程序的Firefox或Chrome。
    • 您无法直接使用Selenium Web驱动程序修改请求标头

答案 1 :(得分:0)

你可以使用无头浏览器渲染网页,但是没有它就可以轻松提取这些数据,试试这个:

import re
import ast
...

def parse_item(self,response):
    regex = re.compile('dataLayer.push\((\{.*\})\);', re.DOTALL)
    html_info = response.xpath('//script[contains(., "dataLayer.push")]').re_first(regex)
    data = ast.literal_eval(html_info)
    yield {'fiyat': data['CD_Fiyat'], 
           'marka': data['CD_marka'], 
           'yil': data['CD_yil']}
    # output an item with {'fiyat': '103500', 'marka': 'Renault', 'yil': '2017'}