scrapy分页抓取网页(什么是Items呢?官方文档Items定义如下:Items)

优采云 发布时间: 2022-02-05 22:14

  scrapy分页抓取网页(什么是Items呢?官方文档Items定义如下:Items)

  什么是物品?官方文档Items定义如下:

  项目

  爬取的主要目标是从非结构化数据源中提取结构化数据,例如网页。Scrapy spider 可以使用 python 的 dict 返回提取的数据。dict虽然使用起来非常方便和熟悉,但缺乏结构,容易打错字段名或返回不一致的数据,尤其是在项目中有多个爬虫的*敏*感*词*情况下。

  为了定义通用的输出数据,Scrapy 提供了 Item 类。Item 对象是一个简单的容器,用于保存爬网数据。它提供了类似字典的 API 和用于声明可用字段的简单语法。

  许多 Scrapy 组件使用 Item 提供的额外信息:exporter 根据 Item 声明的字段导出数据,序列化可以通过 Item 字段的元数据定义,trackref 跟踪 Item 实例以帮助查找内存泄漏(请参阅 Debugging with trackref 内存泄漏)等。

  使用简单的类定义语法和 Field 对象来声明项目。我们打开scrapyspider目录下的items.py文件,编写如下代码声明Item:

  import scrapy

class DoubanMovieItem(scrapy.Item):

# 排名

ranking = scrapy.Field()

# 电影名称

movie_name = scrapy.Field()

# 评分

score = scrapy.Field()

# 评论人数

score_num = scrapy.Field()

  履带式

  在scrapyspider/spiders目录下创建douban_spider.py文件,编写初步代码:

  from scrapy.spiders import Spider

from scrapyspider.items import DoubanMovieItem

class DoubanMovieTop250Spider(Spider):

name = 'douban_movie_top250'

start_urls = ['https://movie.douban.com/top250']

def parse(self, response):

item = DoubanMovieItem()

  这是一个基本的scrapy蜘蛛模型,首先我们需要在Scrapy.spiders中导入Spider类,以及我们刚刚在scrapyspider.items中定义的豆瓣电影项目。然后创建我们自己的爬虫类 DoubanMovieTop250Spider 并继承 Spider 类。scrapy.spiders中有很多不同的爬虫类供我们继承。一般来说,Spider类可以满足要求。(其他爬虫的使用请参考官方文档)。

  蜘蛛

  类scrapy.spider.Spider

  蜘蛛是最简单的蜘蛛。每个其他蜘蛛都必须从这个类继承(包括 Scrapy 附带的其他蜘蛛和您自己编写的蜘蛛)。Spider 不提供任何特殊功能。它只是请求给定的 start_urls/start_requests 并根据返回的结果(结果响应)调用蜘蛛的 parse 方法。

  name 定义蜘蛛名称的字符串。蜘蛛的名字定义了 Scrapy 如何定位(和初始化)蜘蛛,所以它必须是唯一的。但是,您可以在没有任何限制的情况下生成同一个蜘蛛的多个实例。name是spider最重要的属性,是必须的。

  如果蜘蛛爬取单个 网站(单个域),通常的做法是在 网站(域)之后命名蜘蛛(带或不带后缀)。例如,如果蜘蛛正在爬行,蜘蛛通常会被命名为 mywebsite。

  allowed_domains 是可选的。收录允许蜘蛛抓取的域列表。开启 OffsiteMiddleware 后,域名不在列表中的 URL 将不会被跟进。

  start_urls URL 列表。当没有指定具体的 URL 时,蜘蛛会从这个列表开始爬取。因此,要获取的第一个页面的 URL 将是列表之一。后续 URL 将从获取的数据中提取。

  start_requests() 这个方法必须返回一个可迭代的。该对象收录蜘蛛用来抓取的第一个请求。

  当蜘蛛开始爬取并且没有指定 URL 时调用该方法。当指定 URL 时,将调用 make_requests_from_url() 来创建 Request 对象。此方法只会被 Scrapy 调用一次,因此您可以将其实现为*敏*感*词*。

  该方法的默认实现是使用 start_urls 的 url 来生成 Request。

  如果要修改原来爬取了一个网站的Request对象,可以重写这个方法。例如,如果你需要在启动时 POST 到某个 网站,你可以这样写:

  def start_requests(self):

return [scrapy.FormRequest("http://www.example.com/login",

formdata={'user': 'john', 'pass': 'secret'},

callback=self.logged_in)]

def logged_in(self, response):

# here you would extract links to follow and return Requests for

# each of them, with another callback

pass

  make_requests_from_url(url) 该方法接受一个 URL 并返回一个请求对象进行爬取。该方法在初始化请求时被 start_requests() 调用,也用于将 url 转换为请求。

  如果默认不覆盖,在该方法返回的Request对象中,parse()作为回调函数,dont_filter参数也设置为on。(详情请参阅请求)。

  parse(response) 当response没有指定回调函数时,这个方法是Scrapy处理下载的response的默认方法。

  parse 处理响应并返回处理后的数据和/或要遵循的 URL。Spider 对其他 Request 回调函数有相同的要求。

  此方法和其他 Request 回调函数必须返回收录 Request 和/或 Item 的可迭代对象。

  参数:响应(Response)——用于分析的响应

  log(message[, level, component]) 使用 scrapy.log.msg() 方法记录(记录)消息。日志中自动携带蜘蛛的名称属性。有关更多数据,请参阅日志记录。

  closed(reason) 这个函数在蜘蛛关闭时被调用。这个方法提供了一个快捷方式,而不是调用 signals.connect() 来*敏*感*词* spider_close 信号。

  提取网页信息

  我们使用 xpath 语法来提取我们需要的信息。不熟悉xpath语法的同学可以在W3School网站中学习,很快就能上手。首先,我们在chrome浏览器中进入豆瓣电影TOP250页面,按F12打开开发者工具。

  

  点击工具栏左上角类似鼠标的符号图标或Ctrl+Shift+c点击页面中我们想要的元素,在工具栏中查看其在网页HTML源代码中的位置。一般抓的时候,先抓大再抓小的原则。通过观察,我们可以看到该页面上所有电影的信息都位于一个类属性为grid_view的ol标签内的一个li标签中。

  

1

肖申克的救赎

 / The Shawshank Redemption

 / 月黑高飞(港) / 刺激1995(台)

[可播放]

导演: 弗兰克·德拉邦特 Frank Darabont   主演: 蒂姆·罗宾斯 Tim Robbins /...

1994 / 美国 / *敏*感*词* 剧情

9.6

766719人评价

希望让人自由。

...

...

...

  因此,我们按照上述原则爬取所需信息

  from scrapy.spiders import Spider

from scrapyspider.items import DoubanMovieItem

class DoubanMovieTop250Spider(Spider):

name = 'douban_movie_top250'

start_urls = ['https://movie.douban.com/top250']

def parse(self, response):

item = DoubanMovieItem()

movies = response.xpath('//ol[@class="grid_view"]/li')

for movie in movies:

item['ranking'] = movie.xpath(

'.//div[@class="pic"]/em/text()').extract()[0]

item['movie_name'] = movie.xpath(

'.//div[@class="hd"]/a/span[1]/text()').extract()[0]

item['score'] = movie.xpath(

'.//div[@class="star"]/span[@class="rating_num"]/text()'

).extract()[0]

item['score_num'] = movie.xpath(

'.//div[@class="star"]/span/text()').re(ur'(\d+)人评价')[0]

yield item

  Scrapy提取的页面信息内容详细请参考官方文档的相应章节。

  运行爬虫

  在项目文件夹中打开 cmd 并运行以下命令:

  scrapy crawl douban_movie_top250 -o douban.csv

  注意这里的douban_movie_top250是我们刚刚写的爬虫的名字,-o douban.csv是scrapy提供的一个快捷方式,可以将item输出为csv格式

  尝试运行爬虫,为什么没有输出?!!!

  

  在你所有的努力之后你会失败吗?!!!别着急,我们看下一个控制台输出的信息。原来是403错误。这是因为豆瓣给爬虫设置了一个很小的阈值,我们只需要在发送请求时更改请求头user-agent即可。

  更改后的代码在某些地方感觉不同吗?为什么 start_urls 不见了?start_requests 函数有什么作用?还记得刚才对 Spider 类的介绍吗?让我们回过头来回顾一下上面对 start_urls 和 start_requests 函数的介绍。简单来说,通过使用start_requests函数,我们有了更多的权限来处理初始URL,比如这次在初始URL中加入了请求头user_agent。

  再次运行爬虫,我们想要的信息全部下载到douban.scv文件夹中。直接用WPS打开查看信息。

  

  自动翻页

  不要太激动,没发现问题吗?在这种情况下,我们只能抓取到当前页面的 25 部电影的内容。我怎样才能和其他人一起爬下来?实现自动翻页一般有两种方式:

  在页面中找到下一页的地址;根据 URL 的变化规律,自己构建所有的页面地址。

  一般情况下我们使用第一种方式,第二种方式适用于页面的下一页地址是JS加载的情况。今天我们只讲第一种方法。先用Chrome浏览器的开发者工具找到下一页的地址

  

  然后在解析页面的时候,得到下一页的地址,把地址交给调度器(Scheduler)

  from scrapy import Request

from scrapy.spiders import Spider

from scrapyspider.items import DoubanMovieItem

class DoubanMovieTop250Spider(Spider):

name = 'douban_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',

}

def start_requests(self):

url = 'https://movie.douban.com/top250'

yield Request(url, headers=self.headers)

def parse(self, response):

item = DoubanMovieItem()

movies = response.xpath('//ol[@class="grid_view"]/li')

for movie in movies:

item['ranking'] = movie.xpath(

'.//div[@class="pic"]/em/text()').extract()[0]

item['movie_name'] = movie.xpath(

'.//div[@class="hd"]/a/span[1]/text()').extract()[0]

item['score'] = movie.xpath(

'.//div[@class="star"]/span[@class="rating_num"]/text()'

).extract()[0]

item['score_num'] = movie.xpath(

'.//div[@class="star"]/span/text()').re(ur'(\d+)人评价')[0]

yield item

next_url = response.xpath('//span[@class="next"]/a/@href').extract()

if next_url:

next_url = 'https://movie.douban.com/top250' + next_url[0]

yield Request(next_url, headers=self.headers)

  最后再次运行爬虫,打开douban.csv。有没有发现已经获取了所有的电影信息,其中250个不超过1个,不小于250个?

  

  最后,使用 WPS 的过滤功能,您可以过滤任何符合您要求的视频。(ps:外国和尚不总是会念经,记得用WPS打开这个CVS文件,用EXCEL打开会因为中文导致显示异常。)

  结尾

  自从写了这篇 Scrapy 爬虫框架教程后,我越来越觉得把学到的东西导出并没有想象中的那么简单。很多时候,在写了几个小时的教程之后,我发现我仍然无法完美地表达我想要表达的东西。如果有什么不对的地方,请纠正我。有一系列的听证会,并且有艺术行业的专业。我们都互相学习:)

  源码地址:Wooden-Robot/scrapy-tutorial

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线