学习一下爬虫,在网上看了几个教程,毕竟实践后理解才更深,遂自己跑一下。
scrapy的数据流图
scrapy startproject moviespider
Item 对象保存爬取的数据的容器,其提供了类似于词典(dictionary-like) 的API以及用于声明可用字段的简单语法。
这里在items.py定义爬取的内容,电影排名ranking,名称name和评分score。
import scrapy
class MoviespiderItem(scrapy.Item):
# define the fields for your item here like:
ranking = scrapy.Field()
name = scrapy.Field()
score = scrapy.Field()
Spider类中定义抓取对象(域名、URL)以及抓取的规则,创建自己的Spider,必须继承 scrapy.Spider 类, 且定义以下三个属性:
在moviespider/spiders下创建douban_spider.py
import scrapy
from scrapy.spiders import Spider
from moviespider.items import MoviespiderItem
class MovieTop250Spider(Spider):
name = 'movie_top250'
# 如果网站设置有防爬措施,需要添加上请求头信息,不然会爬取不到任何数据
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',
}
start_urls = [
'https://movie.douban.com/top250'
]
# start_requests方法为scrapy的方法,对它进行重写。
# 该方法必须返回一个可迭代对象(iterable)。该对象包含了spider用于爬取的第一个Request。当spider启动爬取并且未制定URL时,该方法被调用。
# 当指定了URL时,make_requests_from_url() 将被调用来创建Request对象。
# 该方法仅仅会被Scrapy调用一次,因此您可以将其实现为生成器。
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url=url, callback=self.parse, headers=self.headers)
def parse(self, response):
pass
打开豆瓣电影top250页面https://movie.douban.com/top250,command+alt+i(windows下为f12)打开开发者工具,用抓取工具(在左上角)选择找到信息所在的标签。
可以找到这里的电影信息在一个叫class属性为grid_view的ol标签内的li标签内,在class=item的div下。
从response里面解析或者说提取出要爬取的信息,可以实用XPath,CSS,beautifulsoup等,我都是第一次接触,都不太熟悉,看了XPath和CSS的提取方法后,个人感觉CSS的语法干净一点,就选择CSS了。beautifulsoup其实感觉也不错,会把html变为python的对象,转化成字典和数组,可能更好用,后面学习一下怎么用。一个讲beautifulsoup的博客链接
def parse(self, response):
item = MoviespiderItem()
for quote in response.css('div.item'):
item['name'] = quote.css('div.info div.hd a span.title::text').extract_first()
item['ranking'] = quote.css('div.pic em::text').extract()
item['score'] = quote.css('div.info div.bd div.star span.rating_num::text').extract()
yield item
next_url = response.css('div.paginator span.next a::attr(href)').extract()
if next_url:
next_url = "https://movie.douban.com/top250" + next_url[0]
print(next_url)
yield scrapy.Request(next_url, headers=self.headers)
不能只让爬虫爬一页的信息,为了爬到完整的信息,需要让它自己翻页去下一页,实现自动翻页一般有两种方法:
我们选择第二种,跟前面一样,在html中用css提取到next页的地址,然后继续发送request请求,这里的代码在上面的parse函数。
在命令行运行
scrapy crawl movie_top250 -o movie_list.csv
部分爬取结果