python能做的100件事03-python爬虫

news/2025/1/16 0:48:31/

文章目录

        • 1. scrapy介绍
        • 2 新建爬虫项目
        • 3 新建蜘蛛文件
        • 4 运行爬虫
        • 5 爬取内容
          • 5.1分析网页结构
          • 5.2 关于Xpath解析
          • 5.3 接着解析电影数据
          • 5.4 下载缩略图
          • 5.5 完整代码
        • 6 最后说明
        • 7 2023.01.23更新
          • 7.1 关于分页
            • 7.1.1 第一种是类似`烂番茄网`这样底部只有一个load more按钮的。每次单击这个按钮,会刷新出新一页的数据。但是每次单击时,地址栏都会携带一个page参数,每次加1.
          • 7.1.2 第二种分页,页面效果类似下面:
          • 7.1.3 第三种分页,瀑布流,不携带分页参数的情况.
          • 7.1.4 第四种分页,可以从下一页按钮获取下一页的链接
          • 7.1.5 第五种分页,模拟点击下一页按钮

本例基于python3和scrapy爬虫框架,不再介绍python的基础知识和爬虫的基本知识。

1. scrapy介绍

Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。

首先安装scrapy:

pip3 install scrapy

2 新建爬虫项目

scrapy startproject pic

项目目录如下:
项目目录

3 新建蜘蛛文件

蜘蛛文件放在spiders目录下,在spiders目录下新建一个蜘蛛文件pic.py,内容如下,并没有设计爬取操作,代码比较简单,看代码中的注释就明白了:

import scrapy#类名自定义,参数固定为scrapy.Spider
class GetImage(scrapy.Spider):name="pic" #蜘蛛名称,必须唯一,一个爬虫项目可以新建多个蜘蛛文件,蜘蛛名不能重复def start_requests(self):#定义要爬取的url    urls=['https://www.rottentomatoes.com/browse/movies_in_theaters/']#请求网页内容,并将内容交给回调函数处理for url in urls:# yield关键字类似return,scrapy.Request发起网页请求,括号内为参数,第一个参数是Request要请求的地址,第二个参数是回调函数,表示Request取到的内容交由该回调函数处理。yield scrapy.Request(url=url,callback=self.parse) #上一方法需要调用的回调函数def parse(self,response):print("------------------------")#此处获取上一步请求的网页内容及请求状态,print(response.body)可以获取网页内容,#因为内容太长,这里不再输出,只输出地址和状态。print(response)

4 运行爬虫

回到项目的根目录,运行如下命令:

scrapy crawl pic # crawl指定类文件中定义的蜘蛛名称pic

可以在运行日志中查看结果,200是网页连接正常的状态码:
在这里插入图片描述

5 爬取内容

上面代码中的网址是烂番茄网的电影页面,建议在测试时尽量选择测试网站进行测试,爬取信息时请遵守网站规定,并确认是否允许爬取.示例中的网页如下图所示:
示例网页

5.1分析网页结构

我们的目标是所有电影的名称和缩略图,首先通过F12查看网页的结构及目标节点的样式,如下图所示:
在这里插入图片描述可以看到只要找tile-dynamic节点下的img标签即可。scrapy中获取节点如下所示:
获取电影名称
运行爬虫,获取到的电影名称如下所示,是一个列表:
电影名称

5.2 关于Xpath解析

此处展示一些Xpath用法:

        #从html根节点查找最外层所有divdivs = response.xpath('//div')#从html根节点查找第一个divdiv = response.xpath('//div[1]')#从上面的div中查找所有p节点,注意此时开头用./不是//ps = div.xpath('./p')#从上面的div中查找所有样式为col-4的p节点ps1 = div.xpath('./p[@class="col-4"]')#循环获取ps1中所有p节点下的img图像地址for p in ps1:#获取节点属性以@开头如@alt,@src,@text等srcs = p.xpath('./img/@src').get() #或者getall(),p节点包含多张图片的情况#更多xpath请参考官方教程:#https://docs.scrapy.org/en/latest/topics/selectors.html#working-with-xpaths
5.3 接着解析电影数据

增加对缩略图的抓取,代码获取的缩略图如下图所示:

获取缩略图

缩略图地址

5.4 下载缩略图

图片下载

下载过程如图所示:
下载过程

下载内容:
下载内容

5.5 完整代码
import scrapy
import ssl
import os
import urllib#定义图片下载地址,请修改为自己的路径
d_path = '/home/ubuntu/下载/albums'#类名自定义,参数固定为scrapy.Spider
class GetImage(scrapy.Spider):name="pic" #蜘蛛名称,必须唯一,一个爬虫项目可以新建多个蜘蛛文件,蜘蛛名不能重复def start_requests(self):#定义要爬取的url    urls=['https://www.rottentomatoes.com/browse/movies_in_theaters/']#请求网页内容,并将内容交给回调函数处理for url in urls:# yield关键字类似return,scrapy.Request发起网页请求,括号内为参数,第一个参数是Request要请求的地址,第二个参数是回调函数,表示Request取到的内容交由该回调函数处理。yield scrapy.Request(url=url,callback=self.parse) #上一方法需要调用的回调函数def parse(self,response):print("--------------------------")#此处获取上一步请求的网页内容及请求状态,print(response.body)可以获取网页内容,#因为内容太长,这里不再输出,只输出地址和状态。print(response)#获取页面所有电影节点#xpath方式获取 //表示从页面根节点开始查找,查找tile-tynamic下的img标签#然后获取img标签下的alt属性,这里alt属性是电影的名字。#getall()表示获取所有匹配项,get()获取第一个匹配项names = response.xpath('//tile-dynamic/img/@alt').getall()#获取页面所有电影缩略图地址albums = response.xpath('//tile-dynamic/img/@src').getall()for index,album in enumerate(albums):#循环取出缩略图地址,交由函数downImg来完成图片下载#并传入参数name,用作下载的缩略图命名self.downImg(album,names[index])#图片下载方法def downImg(self,album,name):try:#下载图片,参数第一个是缩略图地址,第二个参数是文件保存地址+文件名称+后缀名urllib.request.urlretrieve(album,d_path+"/" + name + ".jpg")except Exception as e:print('下载异常:')print(e)passprint ('下载图片:' + name)

6 最后说明

一个简单的图片爬虫就完成了,一个功能复杂的爬虫,还需要解决登陆,分页,或者爬取到结果后入库等操作,这里就不多做解释,以后有空会更新登陆,分页等其他功能,没有空就不更新了。最后还要说明一点,爬取网络内容时请遵守相关法律法规,和网站规则。一般网站的根目录下都有robots.txt文件,请确保遵循了robots.txt的规则。比如烂番茄网的robots.txt规则如下:
robots
Disallow:/search 表示不允许爬取 /search下的所有网页。

7 2023.01.23更新

7.1 关于分页
7.1.1 第一种是类似烂番茄网这样底部只有一个load more按钮的。每次单击这个按钮,会刷新出新一页的数据。但是每次单击时,地址栏都会携带一个page参数,每次加1.

loadmore在这里插入图片描述
在抓取时抓取地址添加一个参数并且循环增加这个page参数即可。这种页面在不知道总页数是多少页的情况下,我们可以自由选择要抓取的页数,或者一个很大的数去抓取全部数据。代码示例如下:

分页部分
异常处理
关于下载图片时的异常如:

异常
是因为这张图片的名字中包含特殊字符<无法识别为路径,创建图片失败所致,在name中去掉标记即可,示例如下:
去掉标记
然后这张图片就正常了:
在这里插入图片描述
在你们自己的文件中需要根据异常信息自己处理.

7.1.2 第二种分页,页面效果类似下面:

yema这种情况可以抓取分页条来获得最大页码,之后同样拼接分页参数,处理同上不再赘述.

7.1.3 第三种分页,瀑布流,不携带分页参数的情况.

以搜狗图像为例,分析每次滑动鼠标出现xhr请求的地址就会发现,每次从接口请求48张图片,只是开始的位置不一样,即参数中的start:
在这里插入图片描述

在这里插入图片描述
所以我们只需要抓取这个接口的数据即可,每次抓取更新start参数值.scrapy抓取https://pic.sogou.com/napi/pc/searchList?mode=1&start=0&xml_len=48&query=情侣头像的结果如下:
在这里插入图片描述从item节点里解析出图片的url地址并下载即可.

7.1.4 第四种分页,可以从下一页按钮获取下一页的链接

在这里插入图片描述
如上如所示,只要抓取a标签的href值即可获取下一页地址.这里的地址是相对地址,需要手动拼接http://www.xxx.com部分.当然,不是所有的网站都可以从下一页的链接中获取地址.只适用于部分情况.

7.1.5 第五种分页,模拟点击下一页按钮

需要借助 selenium 或者 splash 包来实现.后面再更新.


http://www.ppmy.cn/news/18925.html

相关文章

常见流对象的使用

文章目录一、缓冲流字节缓冲流字符缓冲流二、转换流字符输入转换流字符输出转换流三、对象序列化对象序列化对象反序列化四、打印流PrintStreamPrintWriter一、缓冲流 缓冲流&#xff1a;也叫高效流或者高级流&#xff0c;我们之前学的字节流称为原始流&#xff0c;缓冲流自带…

JUC面试(七)——CountDownLatchCyclicBarrierSemaphore

CountDownLatch 概念 让一些线程阻塞直到另一些线程完成一系列操作才被唤醒 CountDownLatch主要有两个方法&#xff0c;当一个或多个线程调用await方法时&#xff0c;调用线程就会被阻塞。其它线程调用CountDown方法会将计数器减1&#xff08;调用CountDown方法的线程不会被…

2023年大年初一 —— 牛客网刷题经验分享~

2023年大年初一 —— 牛客网刷题经验分享~&#x1f60e;大年初一 —— 牛客网刷题经验分享~&#x1f60e;)前言&#x1f64c;BC94 反向输出一个四位数 &#x1f60a;BC95 小乐乐与进制转换 &#x1f60a;BC96 [NOIP2015]金币&#x1f60a;BC97 回文对称数 &#x1f60a;总结撒花…

Kubernetes:开源 K8s 管理工具 Rancher 认知

写在前面 博文内容涉及Rancher 的介绍&#xff0c;集群内安装查看 Rancher 的基本功能理解不足小伙伴帮忙指正 我所渴求的&#xff0c;無非是將心中脫穎語出的本性付諸生活&#xff0c;為何竟如此艱難呢 ------赫尔曼黑塞《德米安》 Rancher 介绍 Rancher 是一个 Kubernetes 管…

23种设计模式(二十二)——访问者模式【行为变化】

文章目录 意图什么时候使用访问者真实世界类比访问者模式的实现访问者模式的优缺点亦称:Visitor 意图 封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于其内部各个元素的新操作。 什么时候使用访问者 1、如果你需要对一个复杂对象…

【new操作符做了什么 —— js】

&#x1f9c1;个人主页&#xff1a;个人主页 ✌支持我 &#xff1a;点赞&#x1f44d;收藏&#x1f33c;关注&#x1f9e1; 文章目录new操作符具体做了什么&#xff1f;&#x1f388;创建了一个空的对象✨将空对象的原型&#xff0c;指向于构造函数的原型&#x1f367;将空对象…

Tkinter的Menu与Messagebox

菜单控件Menu 在当前界面的左上角创建一个菜单&#xff0c;可创建二级菜单、三级菜单等等 具体语法&#xff1a; 创建一个菜单&#xff0c;并命名为menu menutkinter.Menu(root) 创建menu菜单的列表&#xff0c;并命名为filemenu filemenutkinter.Menu(menu,tearoff0) 在…

代码随想录--字符串习题总结

代码随想录–字符串习题总结 1.LeetCode344 反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1&…