前言:
而今咱们对“scrapy爬取豆瓣电影top250图片”大体比较珍视,我们都需要知道一些“scrapy爬取豆瓣电影top250图片”的相关知识。那么小编也在网上汇集了一些对于“scrapy爬取豆瓣电影top250图片””的相关文章,希望小伙伴们能喜欢,朋友们一起来了解一下吧!之前的文章用代码实践了requests和BeautifulSoup4库抓取豆瓣电影评论,今天总结一下scrapy爬虫框架的使用方法。涉及到以下两点内容:
scrapy爬虫框架的结构如何使用scrapy实现一个豆瓣电影评论爬虫scrapy框架原理
scrapy爬虫框架采用"5+2"的结构,包括以下7个部分:
1). Spider: 负责如何向Engine提交请求,如何解析Engine发送来的响应结果;
2). Engine:整个框架的引擎,负责转发请求、响应和item;
3). Scheduler:对来自Engine的请求进行调度。
4). Downloader:向服务器发起实际的网络请求,并将响应结果发送给Engine;
5). Item Pipelines:对Spider的解析结果进行进一步处理,比如数据清洗、保存等;
6). Downloader Middleware:实现更多自定义功能,此处不介绍;
7). Spider Middleware:同上;
开发者在使用scrapy爬虫框架时重点需要关注的是Spider和Item Pipelines如何编写。在希望实现更多高级功能时需要关注两个中间件的使用。
豆瓣电影页面分析
打开豆瓣电影主页和chrome开发者工具,刷新一次页面,如下图所示:
可以看到向服务端请求电影列表时的url是:
”“
这个url将作为爬虫的起点,其中包含四个请求参数,这里将通过控制"page_limit"参数控制查询到的电影数量。该请求的响应结果如下图所示:
响应结果是一个json格式的数据,每个数据项中包含了电影的名称,评分,封面图位置以及电影的url,爬虫将使用电影url到达电影的评论页面。进入电影评论页面之后,如下图所示:
我们要爬取的内容是电影评论的内容和对应的评分,其中评分用星星数量表示。使用开发者工具检查评论内容元素和星星元素,并且复制Xpath,复制的结果将用于代码中解析上述两个元素的内容。
代码实现
通过对页面部分的分析,爬虫的实现思路如下:
调用查询电影列表api,获取一组电影的url;遍历电影url列表,对于其中每个url:请求评论页,解析想要的内容翻页,转到a
其中可以通过向爬虫传递启动参数控制获取到的电影url数量,以及对于每部电影请求的评论页的数量。
项目结构
scrapy提供了命令行工具,可以方便地创建一个爬虫项目,使用方式参考官方文档。爬虫项目的结构如下:
.├── douban_movies│ ├── __init__.py│ ├── items.py # 自定义的表示爬取内容的数据结构│ ├── middlewares.py│ ├── pipelines.py # item处理的流水线│ ├── settings.py # 项目设置文件│ └── spiders # 包含爬虫实现的文件夹│ ├── __init__.py│ └── spiders.py└── scrapy.cfg
爬虫主体
每个爬虫的任务是向引擎提供新的请求,以及解析响应结果得到item。得到的item会交给pipeline进行处理,处理方式和顺序是可以配置的。爬虫的实现如下:
import scrapyimport jsonfrom ..items import MovieCommentItemclass MovieCommentsSpider(scrapy.Spider): name = 'comments' allowed_domains = ['movie.douban.com'] start_urls = [ "; ] headers = { 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/81.0.4044.113 Safari/537.36 ' } def __init__(self, movie_page_limit=10, comment_page_limit=20): super().__init__(MovieCommentsSpider.name) MovieCommentsSpider.start_urls[0] += '&page_limit=' + str(movie_page_limit) self.comment_page_limit = int(comment_page_limit) def start_requests(self): yield scrapy.Request(url=MovieCommentsSpider.start_urls[0], headers=MovieCommentsSpider.headers, meta={'level': 0}) def parse(self, response): if response.meta['level'] == 0: # find movie urls movies = json.loads(response.body_as_unicode()) for movie in movies['subjects']: url = movie['url'] + '/comments?sort=new_score&status=P' for page in range(self.comment_page_limit): yield scrapy.Request(url + "&start=" + str(page * 20), headers=MovieCommentsSpider.headers, meta={'level': 1}, callback=self.parse) elif response.meta['level'] == 1: # resolve comments rates = response.xpath('//*[@id="comments"]/div/div/h3/span/span[2]/@title') comments = response.xpath('//*[@id="comments"]/div/div/p/span[@class="short"]/text()') if len(rates) != len(comments): return total = len(rates) for idx in range(total): item = MovieCommentItem() item['rate'] = rates[idx].get() item['comment'] = comments[idx].get() yield item
Item的处理方式
对于spider解析的item,用户需要自定义处理流程。对于评论和评分,将会保存在同一个文件中,每行一条数据,评分和评论用“_!_”分割,自定义的处理流程如下:
import reclass MovieCommentPipeline(object): def __init__(self): self.f = None self.text2rate = {'很差': '1', '较差': '2', '还行': '3', '推荐': '4', '力荐': '5'} def open_spider(self, spider): self.f = open('comment.txt', 'w') def close_spider(self, spider): self.f.close() def process_item(self, item, spider): # clean and save item rate = self.text2rate[item['rate'].strip()] comment = re.sub('\n|\r\n|', '', item['comment']) record = '_!_'.join([rate, comment]) self.f.write(record + '\n') return item
定义了处理方法之后,还需要配置处理的顺序,只需要在settings.py中进行设置即可,具体设置如下:
ITEM_PIPELINES = { 'douban_movies.pipelines.MovieCommentPipeline': 300}
设置项是一个字典类型的变量,key是开发者定义的处理方法实现类,value是一个位于0到1000的整数,value小的key会先对Item进行处理。
运行爬虫
启动终端执行,其中两个参数规定查询的电影数量和每部电影评论页的最大数量:
scrapy crawl comments -a movie_page_limit=20 -a comment_page_limit=20
即可得到爬取的数据,保存在comment.txt中,结果如下:
代办事项反爬虫技术页面中js如何处理
标签: #scrapy爬取豆瓣电影top250图片