【问题标题】:Scraping with scrapy用scrapy刮
【发布时间】:2014-07-16 17:41:03
【问题描述】:

我正在尝试用scrapy 更深入地挖掘,但只能得到我正在scrapy 的标题而不是任何细节。这是我到目前为止的代码:

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from tcgplayer1.items import Tcgplayer1Item

class MySpider(BaseSpider):
    name = "tcg"
    allowed_domains = ["http://www.tcgplayer.com/"]
    start_urls = ["http://store.tcgplayer.com/magic/journey-into-nyx?PageNumber=1"]

    def parse(self, response):
        hxs = HtmlXPathSelector(response)
        titles = hxs.select("//div[@class='magicCard']")
        vendor = hxs.select("//tr[@class='vendor']")
        items = []

        for titles in titles:
            item = Tcgplayer1Item()
            item ["cardname"] = titles.select("//li[@class='cardName']/a/text()").extract()
            item ["price"] = vendor.select("//td[@class='price']/br/text()").extract()
            item ["quantity"] = vendor.select("//td[@class='quantity']/td/text()").extract()
            items.append(item)
        return items

我无法获得价格和数量来显示任何结果。每张卡都有几个供应商,每个供应商都有自己的价格和数量。我认为这就是我遇到问题的地方。任何帮助将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    首先,这里是固定版本的代码:

    from scrapy.spider import BaseSpider
    from scrapy.selector import Selector
    from tcgplayer1.items import Tcgplayer1Item
    
    
    class MySpider(BaseSpider):
        name = "tcg"
        allowed_domains = ["http://www.tcgplayer.com/"]
        start_urls = ["http://store.tcgplayer.com/magic/journey-into-nyx?PageNumber=1"]
    
        def parse(self, response):
            hxs = Selector(response)
            titles = hxs.xpath("//div[@class='magicCard']")
            for title in titles:
                item = Tcgplayer1Item()
                item["cardname"] = title.xpath(".//li[@class='cardName']/a/text()").extract()[0]
    
                vendor = title.xpath(".//tr[@class='vendor ']")
                item["price"] = vendor.xpath("normalize-space(.//td[@class='price']/text())").extract()
                item["quantity"] = vendor.xpath("normalize-space(.//td[@class='quantity']/text())").extract()
                yield item
    

    代码存在多个问题:

    • vendor 类名需要包含一个尾随空格:“vendor” - 很难找到
    • 每个项目有多个供应商 - 您需要在循环内定义 vendor
    • 您正在循环中重新定义titles 变量
    • 循环中的xpath表达式应该是相对的.//
    • 使用Selector 而不是已弃用的HtmlXPathSelector
    • 使用xpath() 而不是弃用的select()
    • 使用normalize-space() 消除price 和quantity xpaths 中的换行符和多余空格

    【讨论】:

    • 这真的很接近......唯一的问题是价格和数量与卡片不符。它显示每张卡的相同价格列表......以及数量。不过这更接近了。
    • @user3680812 出了点小问题,我已经更新了代码,请重新检查一下。
    • ".//tr" 做到了……太棒了。
    • @user3680812 很高兴它有帮助。这是一个有趣的问题。如果您认为值得,请考虑接受答案。谢谢。
    • 让这段代码通过 page1 运行到有多少页有多难?
    【解决方案2】:

    首先,你可以改变

    item ["price"] = vendor.select("//td[@class='price']/br/text()").extract()
    item ["quantity"] = vendor.select("//td[@class='quantity']/td/text()").extract()
    

    收件人:

    item ["price"] = titles.select("//td[@class='price']/br/text()").extract()
    item ["quantity"] = titles.select("//td[@class='quantity']/td/text()").extract()
    

    这将确保您只获得所需卡的价格和数量行。

    您可能还必须从选择器中删除 /br 和 /td,因此您的代码将如下所示:

    item ["price"] = titles.select("//td[@class='price']/text()").extract()
    item ["quantity"] = titles.select("//td[@class='quantity']/text()").extract()
    

    【讨论】:

      猜你喜欢
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-01
      • 2020-06-10
      • 2013-09-21
      • 2015-04-02
      相关资源
      最近更新 更多