【问题标题】:How to write a repeat element to each row in scrapy如何在scrapy中将重复元素写入每一行
【发布时间】:2019-05-26 19:18:39
【问题描述】:

我正在用 scrapy 测试我的手。到目前为止,我对取得的进展感到非常兴奋,但我遇到了一个问题,即源网站的数据模型似乎与我当前的 scrapy 输出不一致。

Source 提供 Categories、Type 和 URL 数据——每个类别包含多个类型,每个类型都有一个 URL。

我希望获得一个输出来维护数据的嵌套,其中每一行都关联类别、类型和 URL 分组。

XLM 和 CSV 输出都提供独特的类别,但在每个类别行的列中保存所有后续类型和 url 数据。

来源/示例网站:

<div class="box">
     <div class="coin-img coin-imgfile--9999 coin-img-3"></div>
     <div class="coin-heading">
     <h3>Half-Cents and Cents</h3>
</div>
<ul>
     <li><a href="/auctionprices/category/liberty-cap-half-cent-1793-1797/34">Liberty Cap Half Cent (1793-1797)</a></li>
     <li><a href="/auctionprices/category/draped-bust-half-cent-1800-1808/653">Draped Bust Half Cent (1800-1808)</a></li>
     <li><a href="/auctionprices/category/classic-head-half-cent-1809-1836/654">Classic Head Half Cent (1809-1836)</a></li>
</ul>
</div>
<div class="box">
     <div class="coin-img coin-imgfile--9999 coin-img-5"></div>
     <div class="coin-heading">
     <h3>Two and Three Cents</h3>
</div>
<ul>
     <li><a href="/auctionprices/category/two-cent-1864-1873/670">Two Cent (1864-1873)</a></li>
     <li><a href="/auctionprices/category/three-cent-silver-1851-1873/77">Three Cent Silver (1851-1873)</a></li>
     <li><a href="/auctionprices/category/three-cent-nickel-1865-1889/671">Three Cent Nickel (1865-1889)</a></li>
</ul>
</div>

工作蜘蛛抓取所有必要的数据,但未按需要格式化:

import scrapy

class PCGSSpider(scrapy.Spider):
    name = "pcgs_spider"
    custom_settings = {
        'FEED_FORMAT': 'xml',
        'FEED_URI': 'pcgsspider.xml'
    }
    start_urls = ['abovesample.html']

    def parse(self, response):
        SET_SELECTOR = '.box'
        for pcgs in response.css(SET_SELECTOR):

            CAT_SELECTOR = 'h3 ::text'
            TYPE_SELECTOR = './/ul/li/a/text()'
            URL_SELECTOR = './/ul/li/a/@href'
            yield {
                    'categories': pcgs.css(CAT_SELECTOR).extract(),
                    'types': pcgs.xpath(TYPE_SELECTOR).extract(),
                    'type_url': pcgs.xpath(URL_SELECTOR).extract(),
            }

XML 显示正确的数据,但没有嵌套在每个 URL 及其 TYPE 和 TYPE 及其 CATEGORY 中

-<item>
-<categories>
    <value>Half-Cents and Cents</value>
</categories>
-<types>
    <value>Liberty Cap Half Cent (1793-1797)</value>
    <value>Draped Bust Half Cent (1800-1808)</value>
    <value>Classic Head Half Cent (1809-1836)</value>
</types>
-<type_url>
    <value>/auctionprices/category/lincoln-cent-wheat-reverse-1909-1958/46</value>
    <value>/auctionprices/category/lincoln-cent-modern-1959-date/47</value>
    <value>/auctionprices/category/lincoln-cent-modern-1959-date/47</value>
</type_url>
</item>

这一切都很新,所以请原谅任何无知 - 似乎某种程度的迭代可以解决问题,尽管我不清楚在我的蜘蛛中是否是解决结构的数据和核心的最佳位置完成了。

【问题讨论】:

    标签: python xml scrapy


    【解决方案1】:

    我看到的唯一方法是使用类型和 url 为每个链接复制 CATEGORY 值:

    import scrapy
    
    class PCGSSpider(scrapy.Spider):
        name = "pcgs_spider"
        custom_settings = {
            'FEED_FORMAT': 'xml',
            'FEED_URI': 'pcgsspider.xml'
        }
        start_urls = ['abovesample.html']
    
        def parse(self, response):
            for div_box in response.css("div.box"):
                category = div_box.css("h3 ::text").extract_first()
                for li in div_box.css("ul li"):
                    yield { 'category':category,
                            'type':li.css("a ::text").extract_first(),
                            'url' :li.css("a ::attr(href)").extract_first
                          }
    

    【讨论】:

    • 太棒了!像魅力一样工作 - 尽管我需要处理 url 提取。那里有一些噪音csv &lt;bound method SelectorList.get of [&lt;Selector xpath='descendant-or-self::a/descendant-or-self::*/@href' data='/auctionprices/category/liberty-seated-h'&gt;]&gt;
    • 上次.extract_first方法调用后忘记写()
    【解决方案2】:

    您必须在类别字段上使用 extract_first() 方法而不是 extract()。我从抓取 PCGS 中得到的示例:

    <items>
    <item><categories>Half-Cents and Cents</categories><types>Liberty Cap Half Cent (1793-1797)</types><type_url>/auctionprices/category/liberty-cap-half-cent-1793-1797/34</type_url></item>
    <item><categories>Two and Three Cents</categories><types>Two Cent (1864-1873)</types><type_url>/auctionprices/category/two-cent-1864-1873/670</type_url></item>
    <item><categories>Nickels</categories><types>Shield Nickel (1866-1883)</types><type_url>/auctionprices/category/shield-nickel-1866-1883/81</type_url></item>
    </items>
    

    希望这就是您想要的。

    【讨论】:

    • 谢谢!我用extract_first() 玩了一些,我认为大多数承诺只在类别上。在您的结果中,它是否会继续并复制数百行,每行都有不同的 CATEGORIES + VALUES + URL 组合?当我全部使用 extract_first() 时,我得到 15 行,但只有第一个 TYPE 和 URL 组合,而不是 CATEGORY 中的任何后续内容。仅 CATEGORY 上的 extract_first() 提供与原始代码相同的结果。
    • 好的,现在我明白你要做什么了。不幸的是,我无能为力了;至少现在。
    猜你喜欢
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 2021-12-17
    相关资源
    最近更新 更多