0

此代码不起作用:

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,它只发出第一个请求而不发出回调。我应该如何解决这个问题?

4

1 回答 1

2

规则的顺序很重要。根据CrawlSpider的scrapy docsrules

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

如果我按照 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">
                ...

因此,您使用第二条规则定位的链接<div>在其类中具有“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在规则中使用参数。

于 2013-08-25T11:02:18.053 回答