如果仅遵循一个规则,如何修复scrapy规则

时间:2013-08-25 09:46:28

标签: scrapy web-crawler

此代码无效:

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)我也尝试在第一条规则中添加回调并选择第二条规则的路径(&# 39; // div [@id =" ItemResultList"] / div / div / div / a')并发出请求并且它正常工作。

我也尝试了一种解决方法,我尝试使用Base spider而不是Crawl Spider,它只发出第一个请求并且不会发出回调。 我应该怎么解决这个问题?

1 个答案:

答案 0 :(得分:2)

规则的顺序很重要。根据CrawlSpider的scrapy docs 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">
                ...

因此,您使用第二条规则定位的链接位于<div>,其类别中包含“fl”,因此它们也匹配第一条规则,该规则会查找'//div[@id="body-column-main"]//div[contains(@class,"fl")]'中的所有链接,以及因此, NOT 将使用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参数。