使用Scrapy进行Python递归抓取
我正在尝试制作一个抓取工具,用来提取craigslist上的链接、标题、价格和帖子内容。我已经能够获取价格,但它返回的是页面上每个列表的价格,而不是特定行的价格。我也无法让它继续到下一页进行抓取。
这是我正在使用的教程 - http://mherman.org/blog/2012/11/08/recursively-scraping-web-pages-with-scrapy/
我尝试了这个讨论中的建议,但仍然无法让它工作 - Scrapy Python Craigslist Scraper
我想抓取的页面是 - http://medford.craigslist.org/cto/
在链接价格的变量中,如果我去掉 // 在 span[@class="l2"] 前面,它就不会返回任何价格,但如果我保留它,就会包含页面上的每一个价格。
关于规则,我尝试过调整类标签,但似乎在第一页就卡住了。我在想我可能需要单独的爬虫类?
这是我的代码:
#-------------------------------------------------------------------------------
# Name: module1
# Purpose:
#
# Author: CD
#
# Created: 02/03/2014
# Copyright: (c) CD 2014
# Licence: <your licence>
#-------------------------------------------------------------------------------
from scrapy.spider import BaseSpider
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
from scrapy.selector import *
import sys
class PageSpider(BaseSpider):
name = "cto"
allowed_domains = ["medford.craigslist.org"]
start_urls = ["http://medford.craigslist.org/cto/"]
rules = (Rule(SgmlLinkExtractor(allow=("index\d00\.html", ), restrict_xpaths=('//span[@class="button next"]' ,))
, callback="parse", follow=True), )
def parse(self, response):
hxs = HtmlXPathSelector(response)
titles = hxs.select('//span[@class="pl"] | //span[@class="l2"]')
for title in titles:
item = CraigslistSampleItem()
item['title'] = title.select("a/text()").extract()
item['link'] = title.select("a/@href").extract()
item['price'] = title.select('//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 个回答
4
这个想法很简单:在一个 class="content"
的 div
中找到所有的段落。然后从每个段落中提取出链接、文本链接和价格。需要注意的是,select()
方法现在已经不推荐使用了,建议用 xpath()
来代替。
下面是修改过的 parse()
方法的版本:
def parse(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)
这是我得到的一个示例:
{'description': [u"\n\t\tHave a nice, sturdy, compact car hauler/trailer. May be used for other hauling like equipstment, ATV's and the like, Very solid and in good shape. Parice to sell at only $995. Call Bill at 541 944 2929 top see or Roy at 541 9733421. \n\t"],
'link': [u'/cto/4354771900.html'],
'price': [u'$995'],
'title': [u'compact sturdy car trailer ']}
希望这对你有帮助。