使用python Scrapy抓取动态内容

使用python Scrapy抓取动态内容,python,web-scraping,scrapy,Python,Web Scraping,Scrapy,免责声明:我在StackOverflow上看到过许多其他类似的帖子,并试图以同样的方式来做,但它们在这个网站上似乎不起作用 我正在使用Python Scrapy从koovs.com获取数据 但是,我无法获得动态生成的产品大小。具体地说,如果有人能指导我从链接的下拉菜单中获取“不可用”尺寸标签,我将不胜感激 我可以静态地获取大小列表,但这样做只能获取大小列表,而不能获取可用的大小。据我所知,大小可用性是在浏览器中执行的javascript中动态确定的。Scrapy不是浏览器,无法执行javascr

免责声明:我在StackOverflow上看到过许多其他类似的帖子,并试图以同样的方式来做,但它们在这个网站上似乎不起作用

我正在使用Python Scrapy从koovs.com获取数据

但是,我无法获得动态生成的产品大小。具体地说,如果有人能指导我从链接的下拉菜单中获取“不可用”尺寸标签,我将不胜感激


我可以静态地获取大小列表,但这样做只能获取大小列表,而不能获取可用的大小。

据我所知,大小可用性是在浏览器中执行的javascript中动态确定的。Scrapy不是浏览器,无法执行javascript

如果您同意切换到,以下是示例代码:

from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Firefox()  # can be webdriver.PhantomJS()
browser.get('http://www.koovs.com/only-onlall-stripe-ls-shirt-59554.html?from=category-651&skuid=236376')

# wait for the select element to become visible
select_element = WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.select-size select.sizeOptions")))

select = Select(select_element)
for option in select.options[1:]:
    print option.text

browser.quit()
它打印:

S / 34 -- Not Available
L / 40 -- Not Available
L / 42
请注意,您可以使用Chrome或Safari等其他Web驱动程序来代替Firefox。还可以选择使用无头
PhantomJS
浏览器

如果需要,您也可以将Scrapy与Selenium结合使用,请参阅:


您还可以使用(无需
selenium
和真正的浏览器)解决此问题:

该库使用Splash提供Scrapy+JavaScript集成

按照和的安装说明,启动splash docker容器:

$ docker run -p 8050:8050 scrapinghub/splash
将以下设置放入
settings.py

SPLASH_URL = 'http://192.168.59.103:8050' 

DOWNLOADER_MIDDLEWARES = {
    'scrapyjs.SplashMiddleware': 725,
}

DUPEFILTER_CLASS = 'scrapyjs.SplashAwareDupeFilter'
这是您的示例spider,它可以查看大小可用性信息:

# -*- coding: utf-8 -*-
import scrapy


class ExampleSpider(scrapy.Spider):
    name = "example"
    allowed_domains = ["koovs.com"]
    start_urls = (
        'http://www.koovs.com/only-onlall-stripe-ls-shirt-59554.html?from=category-651&skuid=236376',
    )

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url, self.parse, meta={
                'splash': {
                    'endpoint': 'render.html',
                    'args': {'wait': 0.5}
                }
            })

    def parse(self, response):
        for option in response.css("div.select-size select.sizeOptions option")[1:]:
            print option.xpath("text()").extract()
以下是控制台上打印的内容:

[u'S / 34 -- Not Available']
[u'L / 40 -- Not Available']
[u'L / 42']

我面对这个问题,并通过以下步骤轻松解决

pip安装飞溅
pip安装刮擦飞溅
pip安装scrapyjs

下载并安装

打开docker quickterminal并输入

$ docker run -p 8050:8050 scrapinghub/splash
要设置启动URL,请输入
$docker machine ip default
(我的ip是192.168.99.100),检查docker机器中配置的默认ip


就这样

您必须解释网站的json,例如 及


如果我错了,请纠正我,您可以获得尺码列表,但仅筛选可用尺码有困难?没错!我可以静态地得到它们,这样我只得到尺寸列表,而不知道哪些尺寸可用。我将把这一点添加到问题中。你对硒的使用是否满意?我从来没有真正使用过硒,但如果它只需要获取一些数据,而在实际的刮削过程中不是必需的,那么它就很好了。你能告诉我怎么用吗?帮了我很多忙,两个答案都很好。这两种方法都有效。我想知道使用其中一种方法是否比使用另一种方法有优势?@PraveshJain根据我的理解,如果你对这两种方法都满意,我会坚持使用splash——理论上,这应该更快,因为它根本不涉及真正的浏览器。此外,您可以在非真实屏幕无头环境中使用此选项。它也很容易设置,而且几乎没有对scrapy代码进行任何更改-关键部分是scrapyjs提供的中间件。希望对您有所帮助。$docker run-p8050:8050 scrapinghub/splash-this命令..如何使用cron作业调度器将此命令与scrapy一起自动执行以刮取数据。。让docker进程一直运行显然不是一个好主意。在我按计划时间调用reactor之前,可能需要一些sh脚本吗?@Chelsea the settings.py应该存储在您的项目目录中。项目名称>项目名称>设置。py@Plasmatiger在docker中运行
docker机器ip default
,然后将您的启动URL更改为该URL,为我解决了您的问题。docker工具箱链接已断开…:。(@Anthony-您可以从这里获得docker:docker工具箱适用于不符合和要求的旧Mac和Windows系统。
SPLASH_URL = 'http://192.168.99.100:8050'
DOWNLOADER_MIDDLEWARES = {
    'scrapyjs.SplashMiddleware': 725,
}

DUPEFILTER_CLASS = 'scrapyjs.SplashAwareDupeFilter'
import scrapy
import json
class QuoteSpider(scrapy.Spider):
   name = 'quote'
   allowed_domains = ['quotes.toscrape.com']
   page = 1
   start_urls = ['http://quotes.toscrape.com/api/quotes?page=1']

   def parse(self, response):
      data = json.loads(response.text)
      for quote in data["quotes"]:
        yield {"quote": quote["text"]}
      if data["has_next"]:
          self.page += 1
          url = "http://quotes.toscrape.com/api/quotes?page={}".format(self.page)
          yield scrapy.Request(url=url, callback=self.parse)