这次我抓取的内容有:电影的title,director,评分,名言和详情页的电影简介,一共爬取五个内容。涉及主页的爬取和详情页的爬取。用scrapy可以很简单的实现这次爬取。
此次涉及 的除了scrapy框架外还有正则表达式的编写等知识。
豆瓣250 之前也爬取过,用的selenium自动化,这次用scrapy爬取一次,用于scrapy的初探
首先建立一个project:
scrapy startproject doubanmovie
接下来建立一个爬虫文件:
scrapy genspider doubanspider douban.com
前面两步有不了解的可以看我上一篇文章,有解释
链接:这里找到上一篇文章
接下来就是正式编写爬虫了。
主体当然还是 doubanspider.py 文件了
# _*_ coding:utf-8 _*_
import scrapy
from scrapy.selector import Selector
from doubanmovie.items import DoubanmovieItem
class MovieSpider(scrapy.Spider):
name = "Douban" # 爬虫的名称
# 初始的url
start_urls = [
'https://movie.douban.com/top250?start=0&filter='
]
def parse(self,response):
lis = response.xpath('.//div[@class="article"]/ol[@class="grid_view"]/li')
for li in lis:
item = DoubanmovieItem()
# 创建一个item实例
title = li.xpath('.//div[@class="hd"]/a/span/text()').extract_first()
director = li.xpath('.//div[@class="bd"]/p[1]/text()').re('([\u4e00-\u9fa5]?·?[\u4e00-\u9fa5]+?)\s')[0]
# 这个*[\u4e00-\u9fa5]*是匹配汉字的正则表达式,可以记一下
time_list = li.xpath('.//div[@class="bd"]/p[1]/text()').re('\d+?')
# 用正则提取上映时间,由于是提取出来是一个list,所以用jion方法,组成一个字符串
time = ''.join(time_list)
rate = li.xpath('.//span[@class="rating_num"]/text()').extract_first()
quote = li.xpath('.//p[@class="quote"]/span/text()').extract_first()
detail_link = li.xpath('.//div[@class="hd"]/a/@href').extract_first()
# 因为有几部电影没有名言,所以这里加了一个if判断
if quote:
item['title'] = title
item['director'] = director
item['time'] = time
item['rate'] = rate
item['quote'] = quote
else:
item['title'] = title
item['director'] = director
item['time'] = time
item['rate'] = rate
request = scrapy.Request(url=detail_link,meta={"key":item},callback=self.parse_detail)
# 这里的逻辑需要解释一下,这个回调函数parse_detail,meta参数的解释上一篇有完整的可以去看一下
yield request
# yield关键字其实相当于一个return,每次调用都返回它后面的变量
next_page = response.xpath('//span[@class="next"]/a/@href').extract_first()
# 对页面进行的一个循环,通过回调parse函数,对每个主页都执行一个parse方法
if next_page is not None:
url = response.urljoin(next_page)
yield scrapy.Request(url,callback=self.parse)
def parse_detail(self,response):
item = response.meta['key']
# 回调函数中有一个response.meta方法可以取之前传递进来的值
sele = Selector(response)
short = sele.xpath('.//div[@id="link-report"]/span[1]/text()').extract_first()
item['short'] = short
yield item
如果你仔细看我上一个项目的代码,这个肯定容易理解,很多详细的解释都在上一个里面
上一篇传送门
还有 setting.py,pipelines.py,items.py文件的设置什么的都和上一篇一样,并没有很复杂的设置。
有问题和我交流哦!