scrapy爬取豆瓣电影top250

2018-09-11  本文已影响0人  昵称不再更新

学习scrapy,总结下使用scrapy爬取豆瓣电影的demo,以及中间遇到的问题。

  1. 核心就是一个spider和一个item(爬取电影排名,名称,分数,评分人数,图片url)
class DouBanMovieItem(scrapy.Item):
    rank = scrapy.Field()
    movie_name = scrapy.Field()
    score = scrapy.Field()
    score_num = scrapy.Field()
    pic_url = scrapy.Field()
class DoubanmovieSpider(scrapy.Spider):
    name = 'doubanmovie'
    allowed_domains = ['movie.douban.com/top250']
    start_urls = ['https://movie.douban.com/top250/']

    def parse(self, response):
        item = DouBanMovieItem()
        movies = response.css('ol.grid_view li')
        for movie in movies:
            item['pic_url'] = movie.css('div.pic a::attr(href)').extract()
            item['rank'] = movie.css('div.pic em::text').extract()
            item['movie_name'] = movie.css('div.info > div.hd > a > span:nth-child(1)::text').extract()
            item['score'] = movie.css('div.info > div.bd > div.star > span.rating_num::text').extract()
            item['score_num'] = movie.css('div.info > div.bd > div.star > span:nth-child(4)::text').extract()
            yield item

        next_page = response.css('div.paginator > span.next > a::attr(href)').extract_first()
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

以上代码主要需要测试选择器定位的数据是否正确,对于豆瓣这类网站,肯定有反爬措施,所以一段时间以后上述的选择器可能无法定位到准确的数据,需要更改对应的代码。这通过scrapy shell 来进行调试更加方便。
在执行爬虫的时候,正常爬取了第一页数据,但是在爬取第二页数据的时候爬虫停止了,命令行有以下提示:

2018-09-11 20:56:33 [scrapy.spidermiddlewares.offsite] DEBUG: Filtered offsite request to 'movie.douban.com': <GET https://movie.douban.com/top250?start=25&filter=>
2018-09-11 20:56:33 [scrapy.core.engine] INFO: Closing spider (finished)

如上,第二页的urlhttps://movie.douban.com/top250?start=25&filter=可以通过浏览器正常打开,通过scrapy shell 也可以获取数据。而且程序也没有报错,感觉这里很奇怪,是不是应该抛个异常出来?最后查了下,这个问题是爬虫中定义的允许域allowed_domains=['movie.douban.com/top250']与要爬取的url的域不一致。这里我有个猜测 是不是https://movie.douban.com/top250?start=25&filter=通过?带了参数,scrapy认为域是movie.douban.com而不是movie.douban.com/top250?于是将上面的allowed_domains修改成allowed_domains = ['movie.douban.com']再执行爬虫就可以正常爬取了。或者在调用response.follow()的时候增加一个关键字参数response.follow(next_page, callback=self.parse, dont_filter=True),经验证,这样做也是可以的

上一篇下一篇

猜你喜欢

热点阅读