当前位置 主页 > 服务器问题 > Linux/apache问题 >
import scrapy class DoubanItem(scrapy.Item): ranking = scrapy.Field() # 排名 name = scrapy.Field() # 电影名 introduce = scrapy.Field() # 简介 star = scrapy.Field() # 星级 comments = scrapy.Field() # 评论数 describe = scrapy.Field() # 描述
打开之前在spiders文件夹下创建的爬虫文件movie.py如下所示,以及自动创建了三个变量和一个方法,在parse方法中进行返回数据response的处理,我们需要在start_urls提供爬虫的入口地址。注意爬虫会自动过滤掉allowed_domains之外的域名,因此需要注意这个变量的赋值
# spiders/movie.py import scrapy class MovieSpider(scrapy.Spider): # 爬虫名 name = 'movie' # 允许爬取的域名 allowed_domains = ['movie.douban.com'] # 入口url start_urls = ['https://movie.douban.com/top250'] def parse(self, response): pass
在进行数据爬取之前首先要设置一些网络代理,在settings.py文件内找到USER_AGENT变量修改如下:
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0'
可以在命令行通过如下命令启动名为douban的爬虫:scrapy crawl douban,也可以编写一个启动文件run.py文件如下,运行即可
from scrapy import cmdline cmdline.execute('scrapy crawl movie'.split())
接下来要对爬取到的数据进行过滤,通过Xpath规则可以使我们便捷地选中网页中的指定元素,如下图所示,每个电影条目都包裹在<ol class="grid_view">下的一个<li>标签,因此通过xpath://ol[@class='grid_view']/li 就选中了本页面所有的电影条目。可以通过谷歌浏览器的Xpath插件或者火狐浏览器的ChroPath获得xpath值,在浏览器右键查看元素,弹出如下图所示的开发者工具,其中最右边就是ChroPath插件,它直观地显示了元素的Xpath值: //div[@id='wrapper']//li
爬虫response对象的xpath()方法可以直接处理xpath规则字符串并返回对应的页面内容,这些内容都是选择器对象Selector,可以进一步作细化的内容选取,通过xpath选择出其中的电影名字、简介、评价、星级等内容,即之前在items.py文件中所定义的数据结构DoubanItem。循环遍历每个电影列表从其中爬取到准确的电影信息,并保存为DoubanItem对象item,最后通过yield将item对象从Spiders返回到Item管道。
爬虫除了从页面提取Item数据之外还会爬取url链接从而形成下一页的Request请求,如下图所示为豆瓣页面底部的下一页信息,第二页的参数为"?start=25&filter=",与网站地址https://movie.douban.com/top250拼接起来就可以得到下一页面的地址。和上面一样通过xpath提取该内容,如果不为空,则拼接得到的Request请求yield提交给调度器
最终的爬虫movie.py文件如下
# -*- coding: utf-8 -*- import scrapy from items import DoubanItem class MovieSpider(scrapy.Spider): # 爬虫名 name = 'movie' # 爬取网站的域名 allowed_domains = ['movie.douban.com'] # 入口url start_urls = ['https://movie.douban.com/top250'] def parse(self, response): # 首先抓取电影列表 movie_list = response.xpath("//ol[@class='grid_view']/li") for selector in movie_list: # 遍历每个电影列表,从其中精准抓取所需要的信息并保存为item对象 item = DoubanItem() item['ranking'] = selector.xpath(".//div[@class='pic']/em/text()").extract_first() item['name'] = selector.xpath(".//span[@class='title']/text()").extract_first() text = selector.xpath(".//div[@class='bd']/p[1]/text()").extract() intro = "" for s in text: # 将简介放到一个字符串 intro += "".join(s.split()) # 去掉空格 item['introduce'] = intro item['star'] = selector.css('.rating_num::text').extract_first() item['comments'] = selector.xpath(".//div[@class='star']/span[4]/text()").extract_first() item['describe'] = selector.xpath(".//span[@class='inq']/text()").extract_first() # print(item) yield item # 将结果item对象返回给Item管道 # 爬取网页中的下一个页面url信息 next_link = response.xpath("//span[@class='next']/a[1]/@href").extract_first() if next_link: next_link = "https://movie.douban.com/top250" + next_link print(next_link) # 将Request请求提交给调度器 yield scrapy.Request(next_link, callback=self.parse)