『scrapy爬虫』03. 爬取多个页面(详细注释步骤)
创始人
2025-01-17 03:33:07
0次

目录

    • 1. 分析网页试着拿到多个页面的url
    • 2. 抓取250个电影
    • 3. start_requests的使用
    • 4. 代码规范
      • 导库的优化
      • 关于重写
      • 最终修改后的代码
    • 总结


欢迎关注 『scrapy爬虫』 专栏,持续更新中
欢迎关注 『scrapy爬虫』 专栏,持续更新中

1. 分析网页试着拿到多个页面的url

看到了一个个a标签对应的几页的页码url
在这里插入图片描述
这是1页到3页,因为是top250,总共10页.每一页就是25个,也对应着url中的参数0,25,50````````

https://movie.douban.com/top250?start=0&filter= https://movie.douban.com/top250?start=25&filter= https://movie.douban.com/top250?start=25&filter= 

我们的douban.py

import scrapy from scrapy import Selector  from myscrapy.items import MovieItem   class DoubanSpider(scrapy.Spider):     name = "douban"     allowed_domains = ["movie.douban.com"]# 限制或允许访问的域名列表     start_urls = ["https://movie.douban.com/top250"] # 起始url      def parse(self, response):         myselector=Selector(text=response.text)         # 拿到了所有的li,也就是所有的电影,每一个li代表一个电影,list_items是由250个电影li组成的list         list_items=myselector.css("#content > div > div.article > ol > li")         for list_item in list_items:             movie_item=MovieItem()#新建类的对象             # 电影标题的 Selector             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.hd > a > span:nth-child(1)             movie_item['title']=list_item.css("span.title::text").extract_first() # extract_first()从选择器中提取第一个匹配的数据。             # 电影评分             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > div > span.rating_num             movie_item['score']=list_item.css("span.rating_num::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。             # # 电影影评             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > p.quote > span             movie_item['quato']=list_item.css("span.inq::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。              yield movie_item#把整理得到的数据给管道          # 单个页面selector         # content > div > div.article > div.paginator > a:nth-child(3)         # ::attr(href)表示选取元素的href属性。使用.getall()方法可以获取匹配到的所有元素的href属性值,并将其存储在一个列表中。         hrefs_list=myselector.css('div.paginator > a::attr(href)')         for href in hrefs_list:             url=response.urljoin(href.extract())             print(url) 

cmd运行,可以看到获取了url

scrapy crawl douban 

在这里插入图片描述


2. 抓取250个电影

这里要用到scrapy中的request库,注意不是我们之前的requests这一个s的区别很大,不要导错包了.

我们之前不是定义过一个MovieItem类吗?这个request是scrapy内部定义好的,我们在这里传入的url都会和我们前面的start_urls = ["https://movie.douban.com/top250"] # 起始url 一样用于爬虫.

import scrapy from scrapy import Selector,Request from myscrapy.items import MovieItem   class DoubanSpider(scrapy.Spider):     name = "douban"     allowed_domains = ["movie.douban.com"]# 限制或允许访问的域名列表     start_urls = ["https://movie.douban.com/top250"] # 起始url      def parse(self, response):         myselector=Selector(text=response.text)         # 拿到了所有的li,也就是所有的电影,每一个li代表一个电影,list_items是由250个电影li组成的list         list_items=myselector.css("#content > div > div.article > ol > li")         for list_item in list_items:             movie_item=MovieItem()#新建类的对象             # 电影标题的 Selector             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.hd > a > span:nth-child(1)             movie_item['title']=list_item.css("span.title::text").extract_first() # extract_first()从选择器中提取第一个匹配的数据。             # 电影评分             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > div > span.rating_num             movie_item['score']=list_item.css("span.rating_num::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。             # # 电影影评             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > p.quote > span             movie_item['quato']=list_item.css("span.inq::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。              yield movie_item#把整理得到的数据给管道          # 单个页面selector         # content > div > div.article > div.paginator > a:nth-child(3)         # ::attr(href)表示选取元素的href属性。使用.getall()方法可以获取匹配到的所有元素的href属性值,并将其存储在一个列表中。         hrefs_list=myselector.css('div.paginator > a::attr(href)')         for href in hrefs_list:             url=response.urljoin(href.extract())             # print(url)             # 将 Request 对象加入到爬虫的请求队列中,以便发送请求,相当于对每个页面执行抓取数据             yield Request(url=url) #注意这个Request是来自scrapy的.   from scrapy import Selector,Request 

cmd运行

scrapy crawl douban  -o douban250.csv 

在这里插入图片描述


3. start_requests的使用

修复一个bug(为什么250条数据变多了)?
我们的起始页面start_urls = ["https://movie.douban.com/top250"] # 起始url
但是我们知道,页面的规则,因为是第一页比较特殊,省略了参数0,实际上第一页的url应该是https://movie.douban.com/top250?start=0&filter=,这导致我们重复2次爬取了第一页的数据,出现了2次肖申克的救赎
在这里插入图片描述
解决方案1,直接修改起始页面

start_urls = ["https://movie.douban.com/top250"] # 起始url 改为 start_urls = ["https://movie.douban.com/top250?start=0&filter="] # 起始url 

优雅方案2,start_requests一开始就设置要解析的url,不爬取页面url,告诉爬虫要爬的页面有哪些

import scrapy from scrapy import Selector,Request from myscrapy.items import MovieItem   class DoubanSpider(scrapy.Spider):     name = "douban"     allowed_domains = ["movie.douban.com"]# 限制或允许访问的域名列表     start_urls = ["https://movie.douban.com/top250"] # 起始url      def start_requests(self) :         for page in range(10): #10页             yield Request(url=f'https://movie.douban.com/top250?start={page*25}&filter=')       def parse(self, response):         myselector=Selector(text=response.text)         # 拿到了所有的li,也就是所有的电影,每一个li代表一个电影,list_items是由250个电影li组成的list         list_items=myselector.css("#content > div > div.article > ol > li")         for list_item in list_items:             movie_item=MovieItem()#新建类的对象             # 电影标题的 Selector             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.hd > a > span:nth-child(1)             movie_item['title']=list_item.css("span.title::text").extract_first() # extract_first()从选择器中提取第一个匹配的数据。             # 电影评分             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > div > span.rating_num             movie_item['score']=list_item.css("span.rating_num::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。             # # 电影影评             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > p.quote > span             movie_item['quato']=list_item.css("span.inq::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。              yield movie_item#把整理得到的数据给管道          # # 单个页面selector         # # content > div > div.article > div.paginator > a:nth-child(3)         # # ::attr(href)表示选取元素的href属性。使用.getall()方法可以获取匹配到的所有元素的href属性值,并将其存储在一个列表中。         # hrefs_list=myselector.css('div.paginator > a::attr(href)')         # for href in hrefs_list:         #     url=response.urljoin(href.extract())         #     # print(url)         #     # 将 Request 对象加入到爬虫的请求队列中,以便发送请求,相当于对每个页面执行抓取数据         #     yield Request(url=url) #注意这个Request是来自scrapy的.   from scrapy import Selector,Request 

cmd运行

scrapy crawl douban  -o douban250_true.csv 

在这里插入图片描述


4. 代码规范

导库的优化

在优化 Python 代码的导入语句时,通常会按照一定的规则和顺序进行排序和分组。这些规则和顺序有助于提高代码的可读性和维护性。以下是一般情况下推荐的导入规则和顺序:

  • 标准库导入:首先导入Python标准库中的模块,每个导入语句占一行。
python import os import sys 
  • 第三方库导入:接着导入第三方库或框架的模块,每个导入语句占一行。
python import requests import pandas as pd 

本地应用/模块导入:最后导入项目中的自定义模块或应用程序模块。

python from myapp import utils from myapp.models import User 
  • 空行分隔:在不同类型的导入之间加入空行,以提高可读性。

  • 按字母顺序排序:可以按照字母顺序对每个导入组进行排序,或者使用工具自动排序。

  • 避免通配符导入:尽量避免使用 from module import * 的方式,应该明确导入需要的内容。

  • 别名处理:合理使用别名来简化长模块名,但不要过度缩写或使用难以理解的别名。用一些约定俗成的别名.

import pandas as pd 

可以使用pycharm的快捷整理你的导包书写规范
在这里插入图片描述

关于重写

可以看到警告.
在这里插入图片描述

Signature of method 'DoubanSpider.parse()' does not match signature of the base method in class 'Spider' 

这是因为我们的parse继承的DoubanSpider类的scrapy.Spider,我们按住ctrl点击scrapy.Spider前往观察这个被重写的方法,从图中可以看到这几个def都是重写这个spide的方法
在这里插入图片描述

class DoubanSpider(scrapy.Spider):     def parse(self, response): 

可以看到被重写的方法原型
在这里插入图片描述
统一格式

改为下面代码即可消除警告 def parse(self,response, **kwargs): 

最终修改后的代码

import scrapy from scrapy import Selector,Request from myscrapy.items import MovieItem   class DoubanSpider(scrapy.Spider):     name = "douban"     allowed_domains = ["movie.douban.com"]# 限制或允许访问的域名列表     start_urls = ["https://movie.douban.com/top250"] # 起始url      def start_requests(self) :         for page in range(10): #10页             yield Request(url=f'https://movie.douban.com/top250?start={page*25}&filter=')       def parse(self,response, **kwargs):         myselector=Selector(text=response.text)         # 拿到了所有的li,也就是所有的电影,每一个li代表一个电影,list_items是由250个电影li组成的list         list_items=myselector.css("#content > div > div.article > ol > li")         for list_item in list_items:             movie_item=MovieItem()#新建类的对象             # 电影标题的 Selector             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.hd > a > span:nth-child(1)             movie_item['title']=list_item.css("span.title::text").extract_first() # extract_first()从选择器中提取第一个匹配的数据。             # 电影评分             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > div > span.rating_num             movie_item['score']=list_item.css("span.rating_num::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。             # # 电影影评             # content > div > div.article > ol > li:nth-child(1) > div > div.info > div.bd > p.quote > span             movie_item['quato']=list_item.css("span.inq::text").extract_first()  # extract_first()从选择器中提取第一个匹配的数据。              yield movie_item#把整理得到的数据给管道          # # 单个页面selector         # # content > div > div.article > div.paginator > a:nth-child(3)         # # ::attr(href)表示选取元素的href属性。使用.getall()方法可以获取匹配到的所有元素的href属性值,并将其存储在一个列表中。         # hrefs_list=myselector.css('div.paginator > a::attr(href)')         # for href in hrefs_list:         #     url=response.urljoin(href.extract())         #     # print(url)         #     # 将 Request 对象加入到爬虫的请求队列中,以便发送请求,相当于对每个页面执行抓取数据         #     yield Request(url=url) #注意这个Request是来自scrapy的.   from scrapy import Selector,Request 

总结

大家喜欢的话,给个👍,点个关注!给大家分享更多计算机专业学生的求学之路!

版权声明:

发现你走远了@mzh原创作品,转载必须标注原文链接

Copyright 2024 mzh

Crated:2024-3-1

欢迎关注 『scrapy爬虫』 专栏,持续更新中
欢迎关注 『scrapy爬虫』 专栏,持续更新中
『未完待续』


相关内容

热门资讯

实测交流透视挂!宝玛大厅ai智... 实测交流透视挂!宝玛大厅ai智能透视挂教程,宝玛大厅破解软件经验(本来有挂辅助)1、每一步都需要思考...
总算了解辅助器!朱雀吴江三缺一... 总算了解辅助器!朱雀吴江三缺一ai智能透视辅助挂技巧,朱雀吴江三缺一好像是有挂(有辅助挂细节)朱雀吴...
今日公布透视!九五至尊大厅ai... 今日公布透视!九五至尊大厅ai智能透视插件,九五至尊大厅有没有透视挂窍门(切实有挂技术)1、在九五至...
玩家必看科普开挂!聚闲麻将ai... 玩家必看科普开挂!聚闲麻将ai智能透视辅助挂软件,聚闲麻将总是真的有挂(有辅助挂方式)聚闲麻将能透视...
据报道开挂!旅游娱乐ai智能开... 据报道开挂!旅游娱乐ai智能开挂工具,旅游娱乐辅助工具演示(一直有挂教学)1、全新机制【旅游娱乐ai...
一分钟揭秘开挂!决胜朋来麻将a... 一分钟揭秘开挂!决胜朋来麻将ai智能透视辅助挂教程,决胜朋来麻将真是真的是有挂(有辅助挂总结)1、首...
如何分辨真伪透视!红牛ai智能... 如何分辨真伪透视!红牛ai智能透视攻略,红牛是不是有挂经验(真是有挂技术)1、操作简单,无需红牛手机...
2分钟细说辅助器!江湖大庆麻将... 2分钟细说辅助器!江湖大庆麻将ai智能透视辅助挂攻略,江湖大庆麻将竟然是真的有挂(有辅助挂头条)1、...
总算清楚透视挂!老夫子厅ai智... 总算清楚透视挂!老夫子厅ai智能透视挂技巧,老夫子厅怎么开挂课程(好像发现有挂)老夫子厅破解侠是真的...
解密关于辅助!菜鸟麻将ai智能... 解密关于辅助!菜鸟麻将ai智能透视辅助挂脚本,菜鸟麻将总是存在有挂(有辅助挂存在)1、用户打开应用后...