使用Scrapy和Python 2.7递归抓取Craigslist

1 投票
1 回答
1159 浏览
提问于 2025-04-17 21:23

我在让爬虫程序跟踪广告的下一页时遇到了问题。它总是会跟踪到每一个找到的链接,最后把所有的craigslist页面都抓取回来。我知道问题出在规则设置上,所以我尝试过调整规则,但结果要么只抓到第一页,要么抓到craigslist上的所有页面,或者什么都抓不到。有没有人能帮帮我?

这是我现在的代码:

from scrapy.selector import HtmlXPathSelector
from craigslist_sample.items import CraigslistSampleItem
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.http import Request

class PageSpider(CrawlSpider):
    name = "cto"
    allowed_domains = ["medford.craigslist.org"]
    start_urls = ["http://medford.craigslist.org/cto/"]

    rules = (
        Rule(
        SgmlLinkExtractor(allow_domains=("medford.craigslist.org", )),
        callback='parse_page', follow=True
        ),

    )

        def parse_page(self, response):
        hxs = HtmlXPathSelector(response)
        rows = hxs.select('//div[@class="content"]/p[@class="row"]')

        for row in rows:
            item = CraigslistSampleItem()
            link = row.xpath('.//span[@class="pl"]/a')
            item['title'] = link.xpath("text()").extract()
            item['link'] = link.xpath("@href").extract()
            item['price'] = row.xpath('.//span[@class="l2"]/span[@class="price"]/text()').extract()

            url = 'http://medford.craigslist.org{}'.format(''.join(item['link']))
            yield Request(url=url, meta={'item': item}, callback=self.parse_item_page)


    def parse_item_page(self, response):
        hxs = HtmlXPathSelector(response)

        item = response.meta['item']
        item['description'] = hxs.select('//section[@id="postingbody"]/text()').extract()
        return item

1 个回答

1

你需要为SgmlLinkExtractor指定一个allow参数:

allow(一个正则表达式或列表) – 这是一个正则表达式(或者正则表达式的列表),提取的(绝对)网址必须与之匹配。如果没有提供(或者为空),那么它会匹配所有链接。

rules = (
    Rule(SgmlLinkExtractor(allow='http://medford.craigslist.org/cto/'), 
         callback='parse_page', follow=True),
)

这样就会保留所有在http://medford.craigslist.org/cto/这个网址下的链接。

希望这对你有帮助。

撰写回答