scrapy简单教程以及实战

 

1.scrapy基础

  首先看看本学习视频的学习大纲

 

1.1 简介

  Scrapy是用python实现的一个为了爬取网站数据,提取结构性数据而编写的应用框架。使用Twisted高效异步网络框架来处理网络通信。Scrapy架构:

  关于Scrapy架构各项说明,如下所示:

  • ScrapyEngine:引擎。负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。 此组件相当于爬虫的“大脑”,是 整个爬虫的调度中心。
  • Schedule:调度器。接收从引擎发过来的requests,并将他们入队。初始爬取url和后续在页面里爬到的待爬取url放入调度器中,等待被爬取。调度器会自动去掉重复的url。
  • Downloader:下载器。负责获取页面数据,并提供给引擎,而后提供给spider。
  • Spider:爬虫。用户编些用于分析response并提取item和额外跟进的url。将额外跟进的url提交给ScrapyEngine,加入到Schedule中。将每个spider负责处理一个特定(或 一些)网站。
  • ItemPipeline:负责处理被spider提取出来的item。当页面被爬虫解析所需的数据存入Item后,将被发送到Pipeline,并经过设置好次序
  • DownloaderMiddlewares:下载中间件。是在引擎和下载器之间的特定钩子(specific hook),处理它们之间的请求(request)和响应(response)。提供了一个简单的机制,通过插入自定义代码来扩展Scrapy功能。通过设置DownloaderMiddlewares来实现爬虫自动更换user-agent,IP等。
  • SpiderMiddlewares:Spider中间件。是在引擎和Spider之间的特定钩子(specific hook),处理spider的输入(response)和输出(items或requests)。提供了同样简单机制,通过插入自定义代码来扩展Scrapy功能。

  Scrapy数据流:

  1. ScrapyEngine打开一个网站,找到处理该网站的Spider,并向该Spider请求第一个(批)要爬取的url(s);
  2. ScrapyEngine向调度器请求第一个要爬取的url,并加入到Schedule作为请求以备调度;
  3. ScrapyEngine向调度器请求下一个要爬取的url;
  4. Schedule返回下一个要爬取的url给ScrapyEngine,ScrapyEngine通过DownloaderMiddlewares将url转发给Downloader;
  5. 页面下载完毕,Downloader生成一个页面的Response,通过DownloaderMiddlewares发送给ScrapyEngine;
  6. ScrapyEngine从Downloader中接收到Response,通过SpiderMiddlewares发送给Spider处理;
  7. Spider处理Response并返回提取到的Item以及新的Request给ScrapyEngine;
  8. ScrapyEngine将Spider返回的Item交给ItemPipeline,将Spider返回的Request交给Schedule进行从第二步开始的重复操作,直到调度器中没有待处理的Request,ScrapyEngine关闭。

 

1.2 运行环境

  由于本笔记记录的时间间隔有6,7年,所以在第二次复习的时候,w10,w11都出来了,所以这里记录两种安装环境。

 

1.2.1 Window7

  环境windows7 + python3.6 + scrapy1.40

  scarpy在windows7环境下安装需要安装以下组件,否则报错。

  以下有两种处理方式,这里选择第一种。

  第一种:通过wheel来安装lxml.whl、twisted.whl

  第二种:安装vs2015,并勾选各种支持python的选项

   

  1)在这个网址 http://www.lfd.uci.edu/~gohlke/pythonlibs/下载lxml.whl和twisted.whl对应windows版本和python版本的文件(如图所示): 

  这里windows 7 64位系统不知道为什么要下载win32的版本

  2)安装wheel模块:python3 –m pip install wheel

  3)安装lxml,twisted.

  把下载的包放置在python3.6的download(没有自己创建)下,然后进入该目录。

  4)安装Scrapy即可:python3 –m  install Scrapy 

 

1.1.2 Windows10

  至于windows10 + python3.10 + scrapy2.9.0可能出现以上报错,按照w7方式修复即可,但是我这边目前直接使用pip install scrapy安装即可,没有报错。

 

1.3 创建第一个scrapy项目

  本章目的:

 

  1)创建一个spider

 

  2)获取httpbin.org/get的信息

  代码:

  现在使用cmd来执行scrapy

 

  3)上一步,已经获取到httpbin.org的信息,但是执行在cmd,现在使用直接在pycharm里面直接执行。

 

  4)start_urls 和 start_request并存的优先级。

  通过实验可以看出结果,如果两者并存,start_urls就不生效了

 

  本章总结:

Spider作用

  Resuest(发起请求)

Spider:

  Response(信息的请求)    →    信息的提取

                           再次发起请求

 

1.4 User-Agent设置与scrapy Shell使用     

  在一些网站中使用scrapy 爬取数据的时候会出现403错误,这里可以使用禁用robots协议和伪造浏览器User-Agent来实现。

  现在首先测试爬取豆瓣网的T250的电影,然后查看请求头部。

 

  1)首先创建一个豆瓣的spider.

  然后去爬取豆瓣,发现403错误。

 

  2)现在查看访问 example的请求头部

  Httpbin是一个测试网站,这里spider需要小做更改。打印出回应的body信息,这个body里面包含了很多我们想要的信息,比如请求头等等。

  可以看到,我们的User-agent是scrapy的,所以被阻止掉了。

 

  3)接下来,更改配置文件,使用火狐浏览器的User-Agent.

  更改配置文件,模拟成为火狐浏览器访问。

  再次爬取example,查看User-Agent.

 

  4)现在爬取豆瓣

  返回值为200了,代表正常访问

  总结和技巧

  我们访问网址的时候,一共有三种方式。

1.直接请求URL,在seeting配置文件里面直接设置User-Agent即可。设置之后,不管是shell还是用户终端,都可以直接进行访问,上面已经演示过了。

2.shell访问,在shell访问的时候直接指定用户user-agent,如:

  先进入shell,以上是加了网址的,可以直接进行对这个网址的访问

  3.不指定网址,直接进入shell,然后自己自定义网址操作。

  这个和第二种方式区别不大,只是一个在进入shell之前的时候指定网址,一个在进入shell之后指定网址。

  然后可以通response来获取网页的信息,有了这些信息,我们就可以根据标签去爬数据了。

 

1.5 Xpath与CSS选择器

  上面章节中已经可以通过response来获取整个网页想要的信息,接下来,我们就要提取这些我们需要的信息。

 

1.5.1 Xpath

 

  • / 根节点      /xxx/zzz

  根据html的区块来找到对应的标签,关系为层级父子关系

  比如 /html 里面又包含 head  和  body ,head里面还包含 title

 

  • 匹配任意节点元素

  匹配根下面的所有元素

  跟下面就一个html的最大元素

  然后匹配html下的所有元素,html下有head和body2大元素

  如果直接匹配*,那么也是有head和body2大元素

  匹配body下的所有元素

 

  • //div   选择一个网页选择器的所有元素

  如选择这个网页所有标签为title的元素

  匹配head下的meta元素

 

  • //div[@class=”xxx”]

  例如,选取class属性为info 的div节点

  或者选取class属性为hd的div节点下所有a标签下的span

  或者选取class属性为hd的div节点下所有a标签下href属性的值

 

  • 使用浏览器的xpath直接定位

  如,直接定位到一个电影的名称,使用浏览器的xpath功能

  

  更高级的用法,使用函数

  • text提取文本信息

 

  • position()  选取第几个节点,类似于数组的下标

 

  • last或者直接选取最后一个节点

  由于有时候不知道该节点有多长,所以可以直接使用last选择最后一个节点

 

  • starts-with 匹配属性开头为xx的节点

  如匹配 所有div下a标签下的span,class属性为title开头的节点,并且取出最后一个节点的值,注意,这里外层使用单引号

 

  取出如果所有div或者li标签

 

  • 比较运算符 + 逻辑运算符 + 算数运算符

  把大于9.4评分的电影全部找出来,至于为什么要使用and,占时还不清楚

  或者把找到的结果+0.1然后还大于9.4找出来。

 

  • 提取页面的下一页标签

 

1.5.2 CSS

 

  • .classvalue

  选取类属性为title的元素

 

  • div~p 选取前面有div元素的每个p元素

  例如:选取 前面有a元素的每个span元素

 

  • li span选取li内部所有span元素(不管子节点还是孙节点)

 

  • div>p 选择父节点为div的所有p元素  以及提取值

  例如:找出a标签下所有span并且取出值

  在或者找到li 标签下的a标签并且提取href的值

 

  • [attr=val] 选取attr为val的所有元素

  例如选取class为rating_num的元素

 

  • [attr^=val] 属性值以xx开头的的元素 [attr$=val]属性以xx结尾的元素

  例如找到src属性结尾为jpg的速度,并且提取出来src的值

 

  • [attr*=val]  属性包含xx的元素

  例如提取src属性包含doubanio的元素并提取值

 

  • first-of-type 选取子元素为xx的第一个元素

  例如找到class=hd 下的为a的元素   a为子节点,其实在前面章节 > 已经做到了

  First-child 第一个元素为xx的元素,因为要求hd下面第一个为span的,所以没有找到

 

1.6 提取页面信息

  查看获取下一页电影信息的结果

 

1.7 Scrapy运行及分析

  文章开头其实解释过,但是这里还是用另一篇博客的方式讲解一下。

  何为框架,就相当于一个封装了很多功能的结构体,它帮我们把主要的结构给搭建好了,我们只需往骨架里添加内容就行。scrapy框架是一个为了爬取网站数据,提取数据的框架,我们熟知爬虫总共有四大部分,请求、响应、解析、存储,scrapy框架都已经搭建好了。scrapy是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架,scrapy使用了一种非阻塞(又名异步)的代码实现并发的,Scrapy之所以能实现异步,得益于twisted框架。twisted有事件队列,哪一个事件有活动,就会执行!Scrapy它集成高性能异步下载,队列,分布式,解析,持久化等。

  1.五大核心组件

  引擎(Scrapy)
  框架核心,用来处理整个系统的数据流的流动, 触发事务(判断是何种数据流,然后再调用相应的方法)。也就是负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等,所以被称为框架的核心。

  调度器(Scheduler)
  用来接受引擎发过来的请求,并按照一定的方式进行整理排列,放到队列中,当引擎需要时,交还给引擎。可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址。

  下载器(Downloader)
  负责下载引擎发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理。Scrapy下载器是建立在twisted这个高效的异步模型上的。

  爬虫(Spiders)
  用户根据自己的需求,编写程序,用于从特定的网页中提取自己需要的信息,即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面。跟进的URL提交给引擎,再次进入Scheduler(调度器)。

  项目管道(Pipeline)
  负责处理爬虫提取出来的item,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。

 

2.工作流程

  Scrapy中的数据流由引擎控制,其过程如下:

(1)用户编写爬虫主程序将需要下载的页面请求requests递交给引擎,引擎将请求转发给调度器;

(2)调度实现了优先级、去重等策略,调度从队列中取出一个请求,交给引擎转发给下载器(引擎和下载器中间有中间件,作用是对请求加工如:对requests添加代理、ua、cookie,response进行过滤等);

(3)下载器下载页面,将生成的响应通过下载器中间件发送到引擎;

(4) 爬虫主程序进行解析,这个时候解析函数将产生两类数据,一种是items、一种是链接(URL),其中requests按上面步骤交给调度器;items交给数据管道(数据管道实现数据的最终处理);

 

1.8 scrapy 提取信息存储方式及问题分析

  保存信息方式可以保存到文件中,也可以保存到数据库中

  (上面的代码,文件处理是做做个简单的样子,逻辑并不严谨,比如只能保存一次循环的数据,由于是演示不合理的代码,这里就这么保持吧。)

  查看结果

  上面的方式采用了文件存储,那么spider模块也掺合了存储的事情,那么程序设计以及维护就不太合理和方便了,因为你spider专心做好你爬数据的事情,存储应该交给其他人做才好,不然,每次修改存储,可能会到到spider的代码,这样,代码的耦合性就太重了。

 

1.9 scrapy item 使用与提取信息保存

  简单的使用item来定义提取的信息,这里简单演示仅使用一个name

  接下来可以将值保存成不同的存储类型。

  如:

  csv

 

  Json

  在特殊场景下,json默认使用的是unicode编码,所以这里要指定格式

 

1.10 ItemPipeline详解

 

  首先完成一个需求,如果想保存文件的时候想过滤,比如删除一些字段,那么怎么解决,这里有一个内置的方法。

  首先启动ItemPipeline插件

  保存为csv测试

  查看执行过程,已经过滤掉了

  文件里面肯定也是空的

 

  现在使用Pipeline类的方式来保存信息,如保存成为txt的方式。

  Open_spider:打开文件

  Close_spider:关闭文件

  Process_item:中间的逻辑处理

  执行后查看item.txt

 

  如果现在需要保存2个存储方式,一个csv,一个json,那么我们这里有一种办法,就是开启两个Item_pipelines项。

  现在再将Item_pipelinse设置管道打开。

  再次执行

 

1.11 ItemPipeline获取settings设置信息

  本节课主要目的就是用类方法来获取settings里面的配置信息,比如,这里的json要存储,存储在那个路径,文件名是什么,我们想放入到settings里面,而不是写在代码里面。

  配置文件信息

  至于结果就不演示了

 

1.12 使用pipe实现mysql存储

  本章需求,把数据存储到mysql。当然需要两个前提条件。

1.会使用pymysql模块

2.数据库库以及表准备好

  代码见以下:

  pipelinese

  最后别忘了pipe里面设置存储方式

  查看mysql的结果

 

2.scrapy 项目实战

2.1 scrapy项目需求分析与实现思路详解

 

2.2 scrapy 实战一

  本章目的:

1.创建scrapy 项目。

2.对setting进行设置,比如User-Agent

3.简单的编写,对详情页进行解析

 

  创建项目

  (这里有一步错误,这里就不更正了,执行第二条语句,一定要切换到项目里面)

 

  设置Uset-Agent

 

  简单编写,提取详细页信息

 

  运行测试

 

2.3 scrapy 实战二

  本章目的。

  提取详细页的导演名称,主演,电影别名,电影类型,国家等,由于有些标签没有固定属性,这里使用xpath+re来操作。

  访问测试

 

2.4 scrapy 实战三

  本章主要使用代码优化,引入itemloader方法的使用,优化内容的提取。

 

  编写items

  现在执行爬虫,会发现每个item的值都是列表形式的

  下节课就是将列表给取消。

 

2.5 scrapy 实战四

  上图中是两种对我们已经获取到的数据处理的方式。

  第一种是通过xpath或者css得到的结果,我们进行自己的逻辑处理之后,在传给item,这种比较繁琐,等于自己写大量代码,不推荐。

  第二种,如果直接使用itemloader,那么我们就没有办法对数据去进行处理,因为直接将值传给itemloader了,我们没有办法得到直接的数据,这个怎么办?这个当然有办法,就是item自己有的办法,本章就是讲解这个。

  就是下图中的input_processor和output_processor,等于item早就准备好了方法,数据进来的时候有处理方式,数据出去的时候还可以再处理一遍。

  数据进来的时候,使用mapCompose,这个函数,这个函数和python的map函数使用方式一样。假设 map传入了三个函数f1,f2,f3,这三个函数分别作用是split,join,等,那么就会把使用了map后,f1处理完了之后,会把值传给f2,然后再传给f3.

  下图就是MapCompose的具体使用方式

  接下来在items中演示MapCompose的使用,使数据在pipeline的之前进行处理。

  如果输入到items的数据是字符串类型,那么其实可以省略这些步骤

  现在查看一下执行结果,都依照进出的规则去将字符串处理了

 

2.6 scrapy 实战五

  本章主要补全一些要获取的信息,如电影评分等信息,以及请求下一页的信息完善。

  首先在items里面增加需要抓取的字段。

  接下来抓取新增的信息

  测试结果

  本章结果已经完成了信息的补充,下一页的抓取,最后一节讲解怎么解决存储到数据库。

 

2.7 scrapy 实战六

  本章主要是实现痛过pipelines将数据存储到mongo中。

  记得在settings里面开启

  在mongo里面验证结果

  总结

 

3.Scrapy 反爬机制

3.1 常见反爬机制与应对方式

  User-agent看看是不是浏览器

  Cookie登录来限制访问和ip访问次数来限制访问

  User-agent伪装以及请求延时设置

  接下来的方式下一章讲解

 

3.2 反爬机制应对处理

  User-Agent动态更新

  在scrapy的流程中,给到download之前,我可以使用中间件对request做操作

  本章重新创建一个项目来实现,主要使用DOWNLOADER插件的方法,然后查看User—Agent有没有更新。

  安装fake_useragent模块

  创建测试项目

  老规矩还是把settings配置文件配置,只不过这里配置的是中间件。

  现在编写middleware插件

  现在访问查看UserAgent是否发生改变。

  第一次访问

  第二次访问

  本节课简单讲了换ip代理,但是没有细讲,这里留一个记录吧,后面如果有机会再补充。

  动态获取ip代理,老师源码里面也有,可以自己研究。

 

4.scrapy登录实战

4.1 scrapy Post请求详解

  创建一个scrapy_post的post测试请求项目,由于浏览器默认只能发送get请求,现在来看看scrapy怎么发送post请求

  以下代码模拟怎么发送一个post请求到httpbin.org

  主要注意,starturls是一个变量,不再是start_urls了,然后FormRequest来发送post表单的请求。

  查看执行结果

  以上是测试的form表单post的数据。

 

4.2 scrapy 模拟登陆github

  首先要解析login

  这个玩意的原理就是首先登陆github的地址是一个https://github.com/login,这个界面首先需要get请求,然后提交用户名密码以及token和github所需要的信息是一个post请求,所以这里肯定会有2步操作,一个get获取登录界面,一个post像服务器发送用户名密码。

  所以我们需要分析页面,需要提交的时候我们需要哪些数据才能符合提交要求。

  就是这一步疑惑好久,视频第二遍都没看出这个老师说的原理,终于在网上看到一篇文章,搞清楚了自动登录的过程,视频中老师常说提交post的需要什么utf8,commit字段,我一直郁闷,我怎么知道提交的时候需要这些字段。原来,这个东西是需要踩点的。

  比如,我们登录网页的时候,会有post,我们完全可以在浏览器的调试界面知道这个form需要post哪些数据,我们去模拟出来即可。

  这里可以看到表单需要的数据在登录界面的源代码中,使用input隐藏标签将表单数据隐藏,我们都可以通过xpath或者css获取。

  现在这里新建一个项目,开始github自动登录的过程

  登录访问测试-不成功的结果

  登录访问测试-成功的结果

 

4.3 scrapy cookie处理详解

  接下来,这里仅解释cookie的一些简单事例,暂无实战课程,老师直接讲源码。

  登陆完成了,服务器怎么知道我一直是一个登陆的状态,现在就需要cookie  

 

5.Scrapy爬取图片实战

  本章项目难点过高,如有需要,需要回来温习视频,现阶段不做记录

 

5.1 项目需求分析

  由于年代太久远,360升级了反爬方式,根据xpath定位根本就找不到标签,源码里面啥都没有,就比如视频开头的li标签。整个源代码里面哪里有?

  整个网页都没有li标签。虽然这个实验坐不了,但是老师的源码思路还是保留一份。

  这里也记录一下为什么xpath定位不到的原因。

 

  在写爬虫的时候解析网页,使用最多的解析方式就是xpath解析,但是在使用在使用xpath解析的时候,明明自己写的xpath语句正确,但是返回值还是为空

  原因通常是前端做的一些反爬措施,在编写网页的时候通常省略一层标签,但是被省略的标签浏览器会自动补充,修改成正确的结构。。

  我们通过浏览器进行检查的时候,看到的代码结构是已经被浏览器修改后的,而爬虫获取到的是源代码

  所以根据修改后的xpath解析源代码会找不到相应的元素,返回值自然为空

 

  举例

  浏览器修改后的代码

  xpath语句'/html/body/div[5]/div[3]/div[2]/table/tbody/tr[1]/td[2]/a/@href'

  源码

  缺少一个tbody标签,

  xpath/html/body/div[5]/div[3]/div[2]/table/tr[1]/td[2]/a/@href 将tbody删除

  总结 当使用xpath获取不到向相应的元素的时候,观察一下源码结构,根据源码进行解析。

  而我们的环境更苛刻,整个网页都是动态生成的,根本爬不了。

 

 

 

Giithub自动登录参考: https://blog.csdn.net/qq_63713328/article/details/127779889

Xpath定位不到的原因参考:https://blog.csdn.net/qq_52007481/article/details/124353861

posted @ 2023-06-06 00:09  小家电维修  阅读(599)  评论(1编辑  收藏  举报