【问题标题】:How to use yield instead of print with scrapy selector and selenium?如何使用产量而不是使用scrapy选择器和硒打印?
【发布时间】:2019-03-19 19:09:10
【问题描述】:
from scrapy import Spider
from selenium import webdriver
from scrapy.selector import Selector

class FlipkartSpider(Spider):
    name = 'flipkarttrial1'
    allowed_domains = ['flipkart.com']

    def start_requests(self):
        self.driver = webdriver.Chrome('C:\\Users\\xyz\\chromedriver')
        self.driver.get('https://www.flipkart.com/womens-footwear/heels/pr?sid=osp,iko,6q1&otracker=nmenu_sub_Women_0_Heels')
        sel = Selector(text=self.driver.page_source)
        prices = sel.xpath('//div/div[@class="_1vC4OE"]/text()').extract()
        for price in prices:
            print(price)

    def parse(self, response):
        pass

这里 scraper 打印价格,但是当我使用 yield 时,它会引发错误。我想将价格保存到 csv 文件。如何使用 'yield' 保存数据?

【问题讨论】:

  • 也许你应该解释一下你到底想做什么。
  • yield 语句用于代替函数中的 return 语句来创建生成器,然后用于循环遍历函数的结果。我不确定您期望收益如何在这里为您提供帮助,并解释说这将使人们能够为您的问题提供解决方案。还有什么错误被抛出?
  • 我用 self.driver.get(response.url) 尝试了代码,但它仍然不起作用。浏览器(Chrome)打开,但 url 没有加载。您能否提供一种将价格数据保存到 csv 文件的方法?

标签: python python-3.x selenium-webdriver web-scraping scrapy


【解决方案1】:

您可以轻松地省略 selenium 和 scrapy.Selector,只使用 parse 方法中的响应。

import scrapy

class FlipkartSpider(scrapy.Spider):
    name = 'flipkarttrial1'
    allowed_domains = ['flipkart.com']


    def start_requests(self):
        url = 'https://www.flipkart.com/womens-footwear/heels/pr?sid=osp,iko,6q1&otracker=nmenu_sub_Women_0_Heels'
        yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        prices = response.xpath('//div/div[@class="_1vC4OE"]/text()').extract()
        for price in prices:
            yield {'price':price}

然后使用scrapy crawl flipkarttrial1 -o data.csv -t csv运行它

已编辑:如果你还想要 Selenium,你可以使用 python 的 csv 模块来编写 csv 文件。

start_request 方法必须返回一个scrapy.Request(url, callback) 对象,然后回调方法(在下面的代码中,parse 方法是回调)是完成其余工作的方法。

class FlipkartSpider(Spider):
    name = 'flipkarttrial1'
    allowed_domains = ['flipkart.com']
    start_urls = ['https://www.flipkart.com/womens-footwear/heels/pr?sid=osp,iko,6q1&otracker=nmenu_sub_Women_0_Heels']

    def parse(self, response):
        self.driver = webdriver.Chrome('C:\xyz\chromedriver')
        self.driver.get(response.url)
        sel = Selector(text=self.driver.page_source)
        prices = sel.xpath('//div/div[@class="_1vC4OE"]/text()').extract()

        output = open('output_data.csv', 'w')
        fieldnames = ['price']
        csv_file = csv.DictWriter(output, fieldnames)

        for price in prices:
            yield csv_file.writerow({fieldnames[0]: price})

【讨论】:

  • 没有 Selenium,javascript 不会执行,并且在 csv 表和网站中获得的结果不同。这就是使用硒的原因
  • 我已经更新了答案。是的,scrapy 下载器中间件返回的页面只是原始页面源。
  • 检查错误日志here 和更新的答案
【解决方案2】:

您必须yield 一个正确的 Python 字典,如下所示

我猜你不能从 strat_requests 中产生项目,所以只需执行一个虚拟请求,然后在 parse 方法中产生项目

def start_requests(self):
    yield scrapy.Request(url=“http://ip-api.com/json”, callback=self.parse)

def parse(self, response):
    self.driver = webdriver.Chrome('C:\\Users\\xyz\\chromedriver')
    self.driver.get('https://www.flipkart.com/womens-footwear/heels/pr?sid=osp,iko,6q1&otracker=nmenu_sub_Women_0_Heels')
    sel = Selector(text=self.driver.page_source)
    prices = sel.xpath('//div/div[@class="_1vC4OE"]/text()').extract()
    for price in prices:
        yield {“price": price}

【讨论】:

  • 给我看看你的scrapy日志......你是如何运行scraper的?你是不是像“scrapy crawl spider -o out.csv”一样跑了
  • @Umair 你忘了yield 那里:yield {"price": price}
  • 这是这张图片中的错误报告:link
  • 我无法打开链接,这是私人的。请在您的问题中附上图片
  • 再试一次...已授予权限
猜你喜欢
  • 2015-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多