【问题标题】:How to fix scrapy rules when only one rule is followed仅遵循一条规则时如何修复scrapy规则
【发布时间】:2013-08-25 09:46:27
【问题描述】:

此代码不起作用:

name="souq_com"
allowed_domains=['uae.souq.com']
start_urls=["http://uae.souq.com/ae-en/shop-all-categories/c/"]

rules = (
    #categories
    Rule(SgmlLinkExtractor(restrict_xpaths=('//div[@id="body-column-main"]//div[contains(@class,"fl")]'),unique=True)),
    Rule(SgmlLinkExtractor(restrict_xpaths=('//div[@id="ItemResultList"]/div/div/div/a'),unique=True),callback='parse_item'),
    Rule(SgmlLinkExtractor(allow=(r'.*?page=\d+'),unique=True)),
)

第一条规则得到响应,但第二条规则不起作用。 我确定第二个规则 xpath 是正确的(我已经使用 scrapy shell 尝试过)我还尝试向第一个规则添加回调并选择第二个规则的路径('//div[@id="ItemResultList "]/div/div/div/a') 并发出请求,它工作正常。

我还尝试了一种解决方法,我尝试使用 Base Spider 而不是 Crawl Spider,它只发出第一个请求,不发出回调。 我应该如何解决这个问题?

【问题讨论】:

    标签: scrapy web-crawler


    【解决方案1】:

    规则的顺序很重要。根据scrapy docs为CrawlSpider rules

    如果多个规则匹配同一个链接,将使用第一个,根据在此属性中定义的顺序。

    如果我点击http://uae.souq.com/ae-en/shop-all-categories/c/中的第一个链接,即http://uae.souq.com/ae-en/antique/l/,那么您要关注的项目就在这个结构中

    <div id="body-column-main">
        <div id="box-ads-souq-1340" class="box-container ">...
        <div id="box-results" class="box-container box-container-none ">
            <div class="box box-style-none box-padding-none">
                <div class="bord_b_dash overhidden hidden-phone">
                <div class="item-all-controls-wrapper">
                <div id="ItemResultList">
                    <div class="single-item-browse fl width-175 height-310 position-relative">
                    <div class="single-item-browse fl width-175 height-310 position-relative">
                    ...
    

    因此,您使用第二条规则定位的链接位于 &lt;div&gt; 中,它们的类中有“fl”,因此它们也匹配第一条规则,该规则查找 '//div[@id="body-column-main"]//div[contains(@class,"fl")]' 中的所有链接,因此将 parse_item解析

    简单解决方案:尝试将第二条规则放在“类别”规则之前(unique=True 默认为 SgmlLinkExtractor

    name="souq_com"
    allowed_domains=['uae.souq.com']
    start_urls=["http://uae.souq.com/ae-en/shop-all-categories/c/"]
    
    rules = (
        Rule(SgmlLinkExtractor(restrict_xpaths=('//div[@id="ItemResultList"]/div/div/div')), callback='parse_item'),
    
        #categories
        Rule(SgmlLinkExtractor(restrict_xpaths=('//div[@id="body-column-main"]//div[contains(@class,"fl")]'))),
    
        Rule(SgmlLinkExtractor(allow=(r'.*?page=\d+'))),
    )
    

    另一种选择是将类别页面的第一条规则更改为限制性更强的 XPath,这在各个类别页面中不存在,例如 '//div[@id="body-column-main"]//div[contains(@class,"fl")]//ul[@class="refinementBrowser-mainList"]'

    您还可以为类别页面定义一个正则表达式,并在您的规则中使用accept 参数。

    【讨论】:

    • 它成功了,但你知道为什么我的规则是错误的吗?
    • 不是你的规则错了。我尚未检查您页面中的详细信息,但如果链接与两个规则都匹配,则规则的顺序很重要。见the scrapy doc“如果多个规则匹配同一个链接,将使用第一个,根据它们在此属性中定义的顺序。”
    • @Vanddel,我进一步查看并添加了关于为什么 2 条规则匹配类别页面中的相同链接的解释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    • 2016-10-23
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多