认识爬虫(HTTP/HTTPS、会话技术、Proxy代理)

认识爬虫(HTTP/HTTPS、会话技术、Proxy代理)

本篇讲解爬虫的基本概念,代码案例放在了最后

爬虫概念

概念

网络爬虫是伪装成客户端与服务端进行数据交互的程序

比较重要的两个:伪装、数据交互

在写代码的时候着重在这两件事情上下功夫。首先要把自己伪装成真正的用户,去向服务器发送请求,在这个环节认证通过了,也就是服务器认为你是一个正常的客户,才会给你资源。把资源拿到的时候,伪装的这一步就完成了。接下来就是怎么从各种资源当中提取到有用的信息,这就是数据交互

爬虫的时候,70%左右的时间都在伪装客户端,30%左右的时间在做数据交互

在做爬虫调试的时候,如果出不来数据,就分成两个部分来看。第一部分,确定一下到底向服务器请求数据请求成功了没有,如果没有成功,就是伪装的问题,这时要考虑一下到底哪些参数没有带上,被服务器发现你是个爬虫身份了。在把数据拿到了之后,再看一下交互的问题,为什么明明有数据,但是取不出来,这个就是交互的问题

作用

1、数据采集

自动从网页上抓取结构化或非结构化数据,供分析、统计、机器学习训练、行情监控等使用。

场景:电商价格/库存监控、新闻聚合、舆情监控、产品比价、学术数据采集等。

技术:HTTP 请求库(requests)、HTML 解析(BeautifulSoup、lxml)、并发/分布式抓取(Scrapy、aiohttp、Celery)、数据存储(数据库、CSV、Elasticsearch)。

注意:优先使用公开 API;遵守 robots.txt、网站服务条款和法律;控制频率,避免对目标站点造成负担

2、搜索引擎(这个地方,爬虫只占很少的一部分,大部分都在做页面的存储)

大量抓取网页并建立索引,用于全网搜索、关键词检索和结果排名。爬虫负责发现新页面、抓取页面内容和提取链接构建链接图谱。

场景:通用搜索(Google、Bing)、垂直搜索(招聘、二手房、学术搜索)。

技术:广度/深度优先抓取策略、URL 去重、增量抓取、内容抽取、分布式调度、倒排索引构建、PageRank/排序算法。

注意:抓取策略需兼顾新鲜度与资源消耗;处理重复内容、规范化 URL 和动态页面(JavaScript 渲染)

网页中的爬虫还分为好几种类型:

通用网络类型爬虫:百度、谷歌可以通过搜索词搜到所有网络全栈的内容

聚焦爬虫:从单个网页抓取数据,每个网页的页面布局不一样,写的爬虫也是不一样的

增量式爬虫:开发了一个新网站,网站每天都需要更新一些新的内容,但是自己又没有这么多内容,就需要去抓比较流行的话题页面。抓它的时候,前面的数据已经抓了,后面的数据是慢慢添加进去的,前面的数据抓完了不会再重复抓一次。它更新了什么数据,就抓什么数据,这个是增量式爬虫

DeepWeb:深网爬虫,需要登录表单。登录注册,进入到需要通过用户名和密码登到后台管理之后,抓管理的数据。是一种私有网络,只有授权了之后才能看到,访问这些信息

DarkWeb:暗网爬虫。网络分为表层网络和暗网。暗网的信息是不会直接开通给你的,加密的部分,也不会被谷歌,雅虎,百度等搜索引擎直接显示出来。它需要特殊浏览器,为了各位公民的安全,我国目前没有该类型浏览器且不支持。最初暗网浏览器来自美国军方,后来被泄露出去,不可控了。现在很多交易会用这种浏览器,在这种网络上抓取数据就是暗网爬虫。很多白客和红客把暗网的链接封杀了,所以暗网隐藏的更深,很难被发现。最后提醒一下,强烈建议不要进入暗网

3、模拟操作

模拟用户在浏览器上的操作以完成需要交互或 JS 渲染的任务,例如登录、表单提交、点击、文件下载等。

场景:自动化测试、业务流程自动化、带登录的数据采集、单页应用(SPA)内容抓取。

技术:Selenium、Playwright、Puppeteer(无头/有头浏览器)、脚本化表单填充、Cookie/会话管理。

注意:模拟用户操作比纯静态抓取更耗资源,需合理控制并保持合规,不应绕过身份验证或安全机制

爬虫开发重难点

数据的获取:

开发的难度主要在数据的获取

在抓取数据的时候不能给服务器太多压力。爬虫会极大消耗网络资源,如果消耗太大,人为就会访问不起来

采集的速度:

想要的数据是海量的,不是简单的一两三个 G。几 TB 差不多的。如果采集速度不够,访问的时间过长,也达不到要求。会采用一些并发,分布式的方法来解决速度上的问题。一个爬虫采的比较慢,50 个爬虫在一个网页上采的就会快一些

HTTP 与 HTTPS

HTTP 与 HTTPS 的核心区别在于数据加密机制:HTTP 采用明文传输存在安全风险,而 HTTPS 通过 SSL/TLS 协议实现加密传输,有效保障数据完整性和机密性

网络架构

1、C/S 即 client server

工作方式:客户端是专门开发的程序(桌面客户端或专用设备),通过特定协议与服务器通信,通常保持会话或长连接,处理复杂逻辑或高性能交互

企业内部的财务软件、医院的影像诊断客户端、QQ/早期即时通讯软件的桌面版、某些大型在线游戏的客户端(需要实时通信和低延迟)。银行柜面系统:柜员端是专用客户端,和后台服务保持安全、稳定的连接

2、b/s 即 browser server(主要集中在 b/s 上操作)

工作方式:客户端是浏览器,使用 HTTP/HTTPS 请求服务器,服务器返回 HTML/CSS/JS,前端在浏览器渲染并与用户交互。现代前端会做大量逻辑(单页应用 SPA、前后端分离),但入口仍是浏览器

电子商务网站(淘宝网页版)、邮箱服务(Gmail 网页版)、企业内网管理系统的网页端

3、m/s 即 mobile server

工作方式:客户端是手机原生应用或混合/跨平台应用,通常通过接口(API)与后端通信,支持推送(通知)、离线存储、访问传感器、摄像头、支付等手机特有能力

微信、滴滴出行、Uber、移动银行 App、外卖 App(美团、饿了么)

http 协议

超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。超文本传输协议是一种用于分布式、协作式和超媒体信息系统的应用层协议,是万维网WWW(World Wide Web)的数据通信的基础

请求行

根据 http 标准,http 请求可以使用多种请求方法:

1、定义了三种请求方法:GET、POST 和 HEAD 方法

2、新增了五种请求方法:OPTIONS、PUT、DELETE、TRACE 和 CONNECT 方法

⽅法名称是区分⼤⼩写的,当某个请求所针对的资源不⽀持对应的请求⽅法的时候,服务器应当返
回状态码405(Method Not Allowed);当服务器不认识或者不⽀持对应的请求⽅法时,应返回状态
码501(Not Implemented)

HTTP服务器⾄少应该实现GET和HEAD/POST⽅法,其他⽅法都是可选的,此外除上述⽅法,特定的HTTP服务器⽀持扩展⾃定义的⽅法

常⽤⽅法

GET
1.主要是负责从服务器获取数据
2.URL中添加请求参数,显⽰在地址栏
3.请求字符串限制 1024个字节
⽐ POST 更加⾼效和⽅便。

POST
1.主要负责向服务器提交数据
2.没有⼤⼩限制
⽐ 'GET' 传递数据量⼤,安全性⾼。

请求头

请求头部由关键字/值对组成,每⾏⼀对,关键字和值⽤英⽂冒号 ":" 分隔。请求头部通知服务器有关于客⼾端请求的信息,典型的请求头有:

User-Agent:产⽣请求的浏览器类型;

referer:⻚⾯跳转处,表明产⽣请求的⽹⻚来⾃于哪个URL,告诉服务器我是从哪个链接过来的,⽐如从我主⻚上链接到⼀个朋友那⾥,他的服务器就能够从HTTP Referer中统计出每天有多少⽤⼾点击我主⻚上的链接访问他的⽹站。

A***ept:客⼾端可识别的响应内容类型列表;星号 “ * ” ⽤于按范围将类型分组,⽤ “ / ” 指⽰可接受全部类型,⽤“ type/* ”指⽰可接受 type 类型的所有⼦类型;

A***ept-Language:客⼾端可接受的⾃然语⾔;

A***ept-Encoding:客⼾端可接受的编码压缩格式;

A***ept-Charset:可接受的应答的字符集; 

Host:请求的主机名,允许多个域名同处⼀个IP 地址,即虚拟主机;

connection:连接⽅式(close 或 keepalive);

Cookie:存储于客⼾端扩展字段,向同⼀域名的服务端发送属于该域的cookie;

Content-Length:发送给HTTP服务器数据的⻓度。

Content-Type:具体请求的媒体的类型信息,⼒图 text/html 代表HTML格式,image/gif代表gif图⽚,application/json代表Json类型

Content-Range:响应资源的范围。可以在每次请求中标记请求的资源范围,在连接断开重连时,客⼾端只请求该资源未下载的部分,⽽不是重新请求整个资源,实现断点续传。

Cache-Control:指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另⼀个消息消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、nostore、man-age、max-stake、min-fresh、only-if-cached;响应消息中的指令包括 public、
privete、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age

空⾏

最后⼀个请求头之后是⼀个空⾏,发送回⻋符和换⾏符,通知服务器以下不再有请求头;

请求体

请求体不在 GET ⽅法中使⽤,⽽是在POST ⽅法中使⽤。POST ⽅法适⽤于需要客⼾填写表单的场合。与请求体相关的最常使⽤的是包体类型 Content-Type 和包体⻓度 Content-Length;

HTTP响应格式

(状态⾏,响应头,空⾏,响应正⽂)

状态⾏

状态⾏由 HTTP 协议版本、状态码和状态码的描述⽂本 3 个部分组成,他们之间使⽤空格隔开;
状态码 由三位数字组成,第⼀位数字表⽰响应的类型,常⽤的状态码有五⼤类如下所⽰:

1xx:表⽰服务器已接收了客⼾端请求,客⼾端可继续发送请求;
2xx:表⽰服务器已成功接收到请求并进⾏处理;
3xx:表⽰服务器要求客⼾端重定向;
4xx:表⽰客⼾端的请求有⾮法内容;
5xx:表⽰服务器未能正常处理客⼾端的请求⽽出现意外错误;

状态码描述⽂本有如下取值:

200 OK:表⽰客⼾端请求成功;
400 Bad Request:表⽰客⼾端请求有语法错误,不能被服务器所理解;
401 Unauthonzed:表⽰请求未经授权,该状态代码必须与 WWW-Authenticate 报头域⼀
起使⽤;
403 Forbidden:表⽰服务器收到请求,但是拒绝提供服务,通常会在响应正⽂中给出不提
供服务的原因;
404 Not Found:请求的资源不存在,例如,输⼊了错误的URL;
500 Internal Server Error:表⽰服务器发⽣不可预期的错误,导致⽆法完成客⼾端的请求;
503 Service Unavailable:表⽰服务器当前不能够处理客⼾端的请求,在⼀段时间之后,服
务器可能会恢复正常;

响应头

Allow服务器⽀持哪些请求⽅法(如GET、POST等)。
Date表⽰消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:
25:57GMT。Date描述的时间表⽰世界标准时,换算成本地时间,需要知道⽤⼾所在的时区。
Set-Cookie⾮常重要的header,⽤于把cookie发送到客⼾端浏览器,每⼀个写⼊cookie都会需要
⼀个Set-Cookie。
Expires指定Response的过期时间,从⽽不再缓存它,重新从服务器获取,会更新缓存。过期之
前使⽤本地缓存。降低服务器负载,缩短加载时间。
Content-Type WEB服务器告诉客⼾端⾃⼰响应的对急的类型和字符集。
Content-Encoding:内容编码格式

空⾏

响应头和响应体由空⾏连接。 最后⼀个响应头之后是⼀个空⾏,发送回⻋符和换⾏符,通知客⼾端以下不再有请响应头;

响应体

该响应消息的响应体是⼀个html⽂档。浏览器可以直接识别这个html⽂件。⽽我们访问的是⼀个jsp⽂件,响应回去的是⼀个html⽂件。说明服务器将该jsp翻译成了⼀个html,然后再响应给浏览器。

HTTP三点注意事项

HTTP是⽆连接:⽆连接的含义是限制每次连接只处理⼀个请求。服务器处理完客⼾的请求,并收
到客⼾的应答后,即断开连接。采⽤这种⽅式可以节省传输时间。
HTTP是媒体独⽴的:这意味着,只要客⼾端和服务器知道如何处理的数据内容,任何类型的数据
都可以通过HTTP发送。
HTTP是⽆状态:HTTP协议是⽆状态协议。⽆状态是指协议对于事务处理没有记忆能⼒。缺少状
态意味着如果后续处理需要前⾯的信息,则它必须重传,这样可能导致每次连接传送的数据量增
⼤。另⼀⽅⾯,在服务器不需要先前信息时它的应答就较快。 ps:这种⽆状态的情况,并不适合
我们进⾏业务需求,我们需要保持我们的登录状态,⽅便我们访问。

HTTP请求流程总结

https协议

HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext Transfer
Protocol Secure,超⽂本传输安全协议),是以安全为⽬标的HTTP通道,简单讲是HTTP的安全版
http协议是基于TCP/IP协议的,⽽https是在http协议的基础之上,再加了⼀层SSL/TLS协议,数据在传输过程中是加密的。
HTTPS协议的默认端⼝是443

会话技术

原因

http是⽆状态的,那服务端怎么区分同⼀个⽤⼾的连续请求呢,这就⽤到了会话技术:cookie和
session。

概念

Cookie有时也⽤其复数形式 Cookies。
指某些⽹站为了辨别⽤⼾⾝份、进⾏ session 跟踪⽽储存在⽤⼾本地终端上的数据(通常经过加
密)。最新的规范是 RFC6265 。
Cookie 可以理解为⼀个凭证
1.实际是由服务器发给客⼾端的特殊信息,
2.这些信息以⽂本⽂件的⽅式存放在客⼾端,
3.客⼾端每次向服务器发送请求的时候都会带上这些特殊的信息。
服务器在接收到Cookie以后,会验证Cookie的信息,以此来辨别⽤⼾的⾝份。

Session中⽂经常翻译为会话,其本来的含义是指有始有终的⼀系列动作/消息,⽐如打电话时从拿起电话拨号到挂断电话这中间的⼀系列过程可以称之为⼀个session。这个词在各个领域都有在使⽤,⽽我们web领域,⼀般使⽤的是其本义,⼀个浏览器窗⼝从打开到关闭这个期间。
Session的⽬的则是,在⼀个客⼾从打开浏览器到关闭浏览器这个期间内,发起的所有请求都可以被识别为同⼀个⽤⼾。
⽽实现的⽅式则是,在⼀个客⼾打开浏览器开始访问⽹站的时候,会⽣成⼀个cookie,SessionID,这个ID每次的访问都会带上,⽽服务器会识别这个SessionID并且将与这个SessionID有关的数据保存在服务器上。由此来实现客⼾端的状态识别。因此session是基于cookie的.
Session与Cookie相反,Session是存储在服务器上的数据,只由客⼾端传上来的SessionId来进⾏判定,所以相对于Cookie,Session的安全性更⾼。
⼀般SessionID会在浏览器被关闭时丢弃,或者服务器会验证Session的活跃程度,例如30分钟某⼀个SessionID都没有活跃,那么也会被识别为失效。

Proxy代理

概念

代理实际指代理服务器,它的功能是代替⽤⼾取获取⽹络信息,就像是⼀个⽹络信息的中转站。正常 情况下请求⼀个⽹站时,我们发送请求给web服务器,然后web服务器把响应传回给我们;⽽如果设 置了代理服务器,此时我们就不是直接给web服务器发送请求,⽽是先向代理服务器发送请求,然后 代理服务器再把我们的请求转发给⽬标web服务器,接着web服务器把响应返回给代理服务器,之后 代理服务器再把响应返回给我们。使⽤这样的访问⽅式,我们同样可以正常访问⻚,但是中间经过了代理服务器后,web服务器就不能识别到我们本机的IP了,只能识别代理服务器的IP,这样我们本机的真实IP就被伪装起来了,这就是代理服务器的基本原理和作⽤。

代理的作⽤

突破⾃⾝IP访问限制,访问⼀些⾃⾝IP不能访问的站点。

访问⼀些单位或团体内部资源:⽐如使⽤教育⽹内地址段免费代理服务器,就可以⽤于对教育⽹
开放的各类FTP下载上传,以及各类资料查询共享等服务。

提⾼访问速度:通常代理服务器都设置⼀个较⼤的硬盘缓冲区,当有外界的信息通过时,同时也
将其保存到缓冲区中,当其他⽤⼾再访问相同的信息时,则直接由缓冲区中取出信息,传给⽤
⼾,以提⾼访问速度。

隐藏真实IP:上⽹者也可以通过这种⽅法隐藏⾃⼰的IP,免受攻击。对于爬⾍来说,我们⽤代理
就是为了隐藏⾃⾝IP,防⽌⾃⾝的IP被封锁。

代理对于爬⾍的作⽤

由于爬⾍爬取速度过快,在爬取过程中可能遇到同⼀个IP访问过于频繁的问题,此时⽹站就会让
我们输⼊验证码登录或者直接封锁IP,这样会给爬取带来极⼤的不便。使⽤代理隐藏真实的IP,让服务器误以为是代理服务器在请求⾃⼰。这样在爬取过程中通过不断更换代理,就不会被封锁,可以达到很好的爬取效果。

案例

百度图片爬虫

目的:抓取百度图片信息然后保存

准备工作

建立一个 百度图片爬虫.py 文件,像这样子

爬虫的两个重要步骤:伪装、数据交互

1、抓取图片首先要有网址 url

2、访问网址

3、下载资源

1 和 2 是伪装,访问网址的时候会有一些数据检查,数据的校验。如果校验不成功,就是伪装没做好。第 3 步下载资源就是最后一步,做数据交互的过程

1、网址获取

打开 百度的图片搜索页面

随便搜点啥,比如我搜的是仓鼠。这样

此时,这个页面的网址就是我们想要的资源,url

url = 'https://image.baidu.***/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=&st=-1&fm=index&fr=&hs=0&xthttps=111110&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E4%BB%93%E9%BC%A0'

url = 'https://image.baidu.***/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=&st=-1&fm=index&fr=&hs=0&xthttps=111110&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E4%BB%93%E9%BC%A0'

2、访问网址

引入 request 库(第一次用这个包,需要下载,请欣赏:下载 request 库)

访问 url,我们在向服务器要资源,用 get 拿,拿到之后赋值给到一个变量存下来

打印出来看一下网页都有哪些内容,为了避免乱码,在第一行添加注释:# -*- coding: UTF-8 -*-  
或者 #coding=utf-8,详情请欣赏:# -*- coding: UTF-8 -*-

#coding=utf-8

url = 'https://image.baidu.***/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=&st=-1&fm=index&fr=&hs=0&xthttps=111110&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E4%BB%93%E9%BC%A0'
import requests
res = requests.get(url=url)
print(res.text)

注:这一部分的每一个代码块,会涵盖前面所有代码块的内容,读者无需自己去拼接代码。学到哪里,就看哪里的代码即可

看看一个网站到底有多少资源

在网站页面右键,点击检查,像这样

在元素这个地方可以看到有很多行代码(并且基本上没有展开),有非常丰富的信息

然鹅刚刚的代码运行之后只有这么点儿

<!DOCTYPE html>
<html lang="zh-***">
<head>
    <meta charset="utf-8">
    <title>百度安全验证</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
    <meta name="format-detection" content="telephone=no, email=no">
    <link rel="shortcut icon" href="https://www.baidu.***/favicon.ico" type="image/x-icon">
    <link rel="icon" sizes="any" mask href="https://www.baidu.***/img/baidu.svg">
    <meta http-equiv="X-UA-***patible" content="IE=Edge">
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
    <link rel="stylesheet" href="https://ppui-static-wap.cdn.bcebos.***/static/touch/css/api/mkdjump_aac6df1.css" />
</head>
<body>
    <div class="timeout hide-callback">
        <div class="timeout-img"></div>
        <div class="timeout-title">网络不给力,请稍后重试</div>
        <button type="button" class="timeout-button">返回首页</button>
    </div>
    <div class="timeout-feedback hide-callback">
        <div class="timeout-feedback-icon"></div>
        <p class="timeout-feedback-title">问题反馈</p>
    </div>

<script src="https://ppui-static-wap.cdn.bcebos.***/static/touch/js/mkdjump_v2_21d1ae1.js"></script>
</body>
</html>

所以这是一个伪装失败的结果

伪装失败说明给的参数不够。要加哪些呢?刚刚的界面点击网络,点击Fetch/XHR

名称里有两个响应(鼠标滚轮在页面一直滚会出现好多个,我后来又滚了一下鼠标),点开其中一个,然后点击响应,就会看到好多字段

点击标头,找到请求标头

找到最重要的两个参数之一,user-agent,先把 user-agent 这个参数加进去

headers 是专门放请求标头的,放的是键值对,以字典的形式去传的

url = 'https://image.baidu.***/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=&st=-1&fm=index&fr=&hs=0&xthttps=111110&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E4%BB%93%E9%BC%A0'
import requests
headers = {
    'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36'
}
res = requests.get(url=url, headers=headers)
print(res.text)

现在测一下,我的还是不行(好运体质可能已经能成功提取出来了,不用再加其他的了。跑不出来还得继续加参数)

我还得再去补参数

再加个cookie(如果加这个还不行,那就继续加,请求标头这个页面加满为止。全补全了之后还是不成功就得用另外的方法了,本篇先按正常的来)

我先加 cookie 试试

url = 'https://image.baidu.***/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=&st=-1&fm=index&fr=&hs=0&xthttps=111110&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E4%BB%93%E9%BC%A0'
import requests
headers = {
    'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36',
    'cookie':'BIDUPSID=79B7C797CFA36739ECD9454FD1D7C0F7; PSTM=1730254837; MAWEBCUID=web_ptJslXANsaPQmlsjPKriEDmnUywVaLdVDktwEgsVNXqAPvCTBq; indexPageSugList=%5B%22%E4%B8%8A%E6%B5%B7%E5%B8%82%E8%82%BA%E7%A7%91%E5%8C%BB%E9%99%A2%E7%97%85%E5%81%87%E5%8D%95%22%2C%22%E4%B8%8A%E6%B5%B7%E6%BB%B4%E6%B0%B4%E6%B9%96%E6%99%AF%E5%8C%BA%22%2C%22%E5%88%97%E7%82%B9%E6%98%AF%E4%BB%80%E4%B9%88%22%5D; BAIDUID=75CBC41DBA5E09AFCEA402F9F6F8EAB3:FG=1; H_WISE_SIDS_BFESS=63148_64007_64974_65242_65614_65634_65711_65759_65782_65799_65840_65866_65861_65919_65361_65926_65941_65950_65964_65955_65987_65996_66004_66010_66083_66095; BDSFRCVID=EdIOJeC624xI_kvEWYF3VMWgbOm16zjTH6aoSFhLHmVOw0e2BHbOEG0PAU8g0Kub6jUWogKKKeOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0x5; H_BDCLCKID_SF=tbC8VCDXfII3qbjkq45HMt00qxby26n45g59aJ5nJD_MJhT3Mnjp3pFzDnjuL-baBKDD_tc_QpP-HJ7bQ47dy-uZXptjK6jGWIr9Kl0MLpjlbb0xynoDj4IA3UnMBMni5mOnaIQc3fAKftnOM46JehL3346-35543bRTLnLy5KJWMD***K4-Xj6j-jNbP; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=7; BAIDUID_BFESS=75CBC41DBA5E09AFCEA402F9F6F8EAB3:FG=1; BDSFRCVID_BFESS=EdIOJeC624xI_kvEWYF3VMWgbOm16zjTH6aoSFhLHmVOw0e2BHbOEG0PAU8g0Kub6jUWogKKKeOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0x5; H_BDCLCKID_SF_BFESS=tbC8VCDXfII3qbjkq45HMt00qxby26n45g59aJ5nJD_MJhT3Mnjp3pFzDnjuL-baBKDD_tc_QpP-HJ7bQ47dy-uZXptjK6jGWIr9Kl0MLpjlbb0xynoDj4IA3UnMBMni5mOnaIQc3fAKftnOM46JehL3346-35543bRTLnLy5KJWMD***K4-Xj6j-jNbP; ZFY=ZlCxwpgMfDTBxqLAiDWchNtmHkVj:BCO69CDMU5RTqV8:C; RT="z=1&dm=baidu.***&si=deee809f-2157-41a7-9ed2-b20ac417843c&ss=mhu2fgpv&sl=1&tt=aoq&b***=https%3A%2F%2Ffclog.baidu.***%2Flog%2Fweirwood%3Ftype%3Dperf&ld=bxw&ul=9k45&hd=9k4d"; H_PS_PSSID=63148_64007_65614_65759_65782_65799_65866_65919_65361_65926_65964_65955_65987_65996_66010_66083_66095_66118_66144_66207_66232_66235_66164_66299_66354_66319_66351_66381_66256_66290_66393; arialoadData=false; H_WISE_SIDS=65614_65782_65799_65919_65361_65926_66010_66083_66095_66118_66144_66207_66232_66235_66299_66354_66319_66351_66381_66256_66290; ab_sr=1.0.1_NzZkZTIxZmZlNjViZDZhNWUzYTQ4YTk5OWExNzE3YTkxOTg5YWIzMWVjNjZjYzNlOGJiNTE4MGRkNTViMTYzNDIyOTI2NGFhZGI4MTZhZWQ0NjlmMTU4ZWFkNWIwNzBiM2Q1MTUwMmE3OGI1MWM0MTA5MDk2MmExY2E3MmM5YmUxNTA3MjA3YzNmNmZkNTA0ZDY5Mzg5NmFjZjIzMWM3Zg=='
}
res = requests.get(url=url, headers=headers)
print(res.text)

我的运行之后发现成功了,不用再加了。读者如果还不成功就接着加

回到终端,找到元素,点击最左侧的“选择网页中的响应元素即可进行检查”

然后鼠标随便放到该页面的图片上,就会定位到对应元素代码的位置

鼠标放这段代码上,发现确实是这张图

把这个,img src=""引号里的这个链接复制一下,我的是这个https://img2.baidu.***/it/u=3401987747,2360194403&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=664

到刚刚的网页里,鼠标右键,查看网页源码

在这个页面中 ctrl + f 搜索刚才的链接

直接搜可能发现没有,因为转义的时候有一些符号没有办法正常转义。在链接里有一些拼接符,比如斜杠/,没办法转义,搜里面某一个段就可以搜到,我搜到是 2360194403,定位到之后这个地方有个链接

粘到这https://img2.baidu.***/it/u=3401987747,2360194403\u0026fm=253\u0026fmt=auto\u0026app=138\u0026f=JPEG?w=500\u0026h=664

看一下和原来的链接哪里不一样了

'''
https://img2.baidu.***/it/u=3401987747,2360194403&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=664
https://img2.baidu.***/it/u=3401987747,2360194403\u0026fm=253\u0026fmt=auto\u0026app=138\u0026f=JPEG?w=500\u0026h=664
'''

发现在

https://img2.baidu.***/it/u=3401987747,2360194403

这儿都是一样的,后面 \u0026 其实就是 & 没转录成功的符号。把这里所有的 \u0026 都用 & 来替换一下,替换好之后发现可以正常访问

接下来我们要做的就是把整个信息中的所有这样的链接全部提取出来,看看前面是什么,后面是什么,然后用正则的方法匹配到。最后还要把转义失败的字符转换一下。最后下载下来

#coding=utf-8
# 伪装
url = 'https://image.baidu.***/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=&st=-1&fm=index&fr=&hs=0&xthttps=111110&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E4%BB%93%E9%BC%A0'
import requests,re
headers = {
    'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36',
    'cookie':'BIDUPSID=79B7C797CFA36739ECD9454FD1D7C0F7; PSTM=1730254837; MAWEBCUID=web_ptJslXANsaPQmlsjPKriEDmnUywVaLdVDktwEgsVNXqAPvCTBq; indexPageSugList=%5B%22%E4%B8%8A%E6%B5%B7%E5%B8%82%E8%82%BA%E7%A7%91%E5%8C%BB%E9%99%A2%E7%97%85%E5%81%87%E5%8D%95%22%2C%22%E4%B8%8A%E6%B5%B7%E6%BB%B4%E6%B0%B4%E6%B9%96%E6%99%AF%E5%8C%BA%22%2C%22%E5%88%97%E7%82%B9%E6%98%AF%E4%BB%80%E4%B9%88%22%5D; BAIDUID=75CBC41DBA5E09AFCEA402F9F6F8EAB3:FG=1; H_WISE_SIDS_BFESS=63148_64007_64974_65242_65614_65634_65711_65759_65782_65799_65840_65866_65861_65919_65361_65926_65941_65950_65964_65955_65987_65996_66004_66010_66083_66095; BDSFRCVID=EdIOJeC624xI_kvEWYF3VMWgbOm16zjTH6aoSFhLHmVOw0e2BHbOEG0PAU8g0Kub6jUWogKKKeOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0x5; H_BDCLCKID_SF=tbC8VCDXfII3qbjkq45HMt00qxby26n45g59aJ5nJD_MJhT3Mnjp3pFzDnjuL-baBKDD_tc_QpP-HJ7bQ47dy-uZXptjK6jGWIr9Kl0MLpjlbb0xynoDj4IA3UnMBMni5mOnaIQc3fAKftnOM46JehL3346-35543bRTLnLy5KJWMD***K4-Xj6j-jNbP; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=7; BAIDUID_BFESS=75CBC41DBA5E09AFCEA402F9F6F8EAB3:FG=1; BDSFRCVID_BFESS=EdIOJeC624xI_kvEWYF3VMWgbOm16zjTH6aoSFhLHmVOw0e2BHbOEG0PAU8g0Kub6jUWogKKKeOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0x5; H_BDCLCKID_SF_BFESS=tbC8VCDXfII3qbjkq45HMt00qxby26n45g59aJ5nJD_MJhT3Mnjp3pFzDnjuL-baBKDD_tc_QpP-HJ7bQ47dy-uZXptjK6jGWIr9Kl0MLpjlbb0xynoDj4IA3UnMBMni5mOnaIQc3fAKftnOM46JehL3346-35543bRTLnLy5KJWMD***K4-Xj6j-jNbP; ZFY=ZlCxwpgMfDTBxqLAiDWchNtmHkVj:BCO69CDMU5RTqV8:C; RT="z=1&dm=baidu.***&si=deee809f-2157-41a7-9ed2-b20ac417843c&ss=mhu2fgpv&sl=1&tt=aoq&b***=https%3A%2F%2Ffclog.baidu.***%2Flog%2Fweirwood%3Ftype%3Dperf&ld=bxw&ul=9k45&hd=9k4d"; H_PS_PSSID=63148_64007_65614_65759_65782_65799_65866_65919_65361_65926_65964_65955_65987_65996_66010_66083_66095_66118_66144_66207_66232_66235_66164_66299_66354_66319_66351_66381_66256_66290_66393; arialoadData=false; H_WISE_SIDS=65614_65782_65799_65919_65361_65926_66010_66083_66095_66118_66144_66207_66232_66235_66299_66354_66319_66351_66381_66256_66290; ab_sr=1.0.1_NzZkZTIxZmZlNjViZDZhNWUzYTQ4YTk5OWExNzE3YTkxOTg5YWIzMWVjNjZjYzNlOGJiNTE4MGRkNTViMTYzNDIyOTI2NGFhZGI4MTZhZWQ0NjlmMTU4ZWFkNWIwNzBiM2Q1MTUwMmE3OGI1MWM0MTA5MDk2MmExY2E3MmM5YmUxNTA3MjA3YzNmNmZkNTA0ZDY5Mzg5NmFjZjIzMWM3Zg=='
}
res = requests.get(url=url, headers=headers)
url_data = res.text
img_url_list_data = re.findall(r'"thumburl":"(.+?)"', url_data)
# print(img_url_list_data)
count = 1
for i in img_url_list_data:
    new_img_url = i.replace(r'\u0026','&')
    # print(new_img_url)
    img_data = requests.get(new_img_url)
    byt_img_content = img_data.content
    with open(f'仓鼠{count}.png', 'wb') as f:
        f.write(byt_img_content)
    count += 1
# 交互
'''
https://img2.baidu.***/it/u=3401987747,2360194403&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=664
https://img2.baidu.***/it/u=3401987747,2360194403&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=664
'''

这样,第一页就抓取完毕了。我们还要继续抓,现实生活中没有只抓第一页的

盯到 网络 这个地方,点 Fetch/XHR

先清空一下,然后用滚轮在网页上滚滚,会出现新的名称,点开可以看到链接

把链接都拿过来看看有什么新发现,最好多找一点儿,不要就两三个

找了4个,发现在 pn 这里是 30 的倍数,gsm 也不一样

'''
https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn=60&rn=30&nojc=0&gsm=3c&newReq=1
https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn=120&rn=30&nojc=0&gsm=78&newReq=1
https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn=90&rn=30&nojc=0&gsm=5a&newReq=1
https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn=30&rn=30&nojc=0&gsm=96&newReq=1
'''

新开个文件,多页抓取.py

#coding=utf-8
'''
https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn=60&rn=30&nojc=0&gsm=3c&newReq=1
https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn=120&rn=30&nojc=0&gsm=78&newReq=1
https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn=90&rn=30&nojc=0&gsm=5a&newReq=1
https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn=30&rn=30&nojc=0&gsm=96&newReq=1
'''
import requests, re
headers = {
    'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36',
    'cookie':'BIDUPSID=79B7C797CFA36739ECD9454FD1D7C0F7; PSTM=1730254837; MAWEBCUID=web_ptJslXANsaPQmlsjPKriEDmnUywVaLdVDktwEgsVNXqAPvCTBq; indexPageSugList=%5B%22%E4%B8%8A%E6%B5%B7%E5%B8%82%E8%82%BA%E7%A7%91%E5%8C%BB%E9%99%A2%E7%97%85%E5%81%87%E5%8D%95%22%2C%22%E4%B8%8A%E6%B5%B7%E6%BB%B4%E6%B0%B4%E6%B9%96%E6%99%AF%E5%8C%BA%22%2C%22%E5%88%97%E7%82%B9%E6%98%AF%E4%BB%80%E4%B9%88%22%5D; BAIDUID=75CBC41DBA5E09AFCEA402F9F6F8EAB3:FG=1; H_WISE_SIDS_BFESS=63148_64007_64974_65242_65614_65634_65711_65759_65782_65799_65840_65866_65861_65919_65361_65926_65941_65950_65964_65955_65987_65996_66004_66010_66083_66095; BDSFRCVID=EdIOJeC624xI_kvEWYF3VMWgbOm16zjTH6aoSFhLHmVOw0e2BHbOEG0PAU8g0Kub6jUWogKKKeOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0x5; H_BDCLCKID_SF=tbC8VCDXfII3qbjkq45HMt00qxby26n45g59aJ5nJD_MJhT3Mnjp3pFzDnjuL-baBKDD_tc_QpP-HJ7bQ47dy-uZXptjK6jGWIr9Kl0MLpjlbb0xynoDj4IA3UnMBMni5mOnaIQc3fAKftnOM46JehL3346-35543bRTLnLy5KJWMD***K4-Xj6j-jNbP; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=7; BAIDUID_BFESS=75CBC41DBA5E09AFCEA402F9F6F8EAB3:FG=1; BDSFRCVID_BFESS=EdIOJeC624xI_kvEWYF3VMWgbOm16zjTH6aoSFhLHmVOw0e2BHbOEG0PAU8g0Kub6jUWogKKKeOTH6KF_2uxOjjg8UtVJeC6EG0Ptf8g0x5; H_BDCLCKID_SF_BFESS=tbC8VCDXfII3qbjkq45HMt00qxby26n45g59aJ5nJD_MJhT3Mnjp3pFzDnjuL-baBKDD_tc_QpP-HJ7bQ47dy-uZXptjK6jGWIr9Kl0MLpjlbb0xynoDj4IA3UnMBMni5mOnaIQc3fAKftnOM46JehL3346-35543bRTLnLy5KJWMD***K4-Xj6j-jNbP; ZFY=ZlCxwpgMfDTBxqLAiDWchNtmHkVj:BCO69CDMU5RTqV8:C; RT="z=1&dm=baidu.***&si=deee809f-2157-41a7-9ed2-b20ac417843c&ss=mhu2fgpv&sl=1&tt=aoq&b***=https%3A%2F%2Ffclog.baidu.***%2Flog%2Fweirwood%3Ftype%3Dperf&ld=bxw&ul=9k45&hd=9k4d"; H_PS_PSSID=63148_64007_65614_65759_65782_65799_65866_65919_65361_65926_65964_65955_65987_65996_66010_66083_66095_66118_66144_66207_66232_66235_66164_66299_66354_66319_66351_66381_66256_66290_66393; arialoadData=false; H_WISE_SIDS=65614_65782_65799_65919_65361_65926_66010_66083_66095_66118_66144_66207_66232_66235_66299_66354_66319_66351_66381_66256_66290; ab_sr=1.0.1_NzZkZTIxZmZlNjViZDZhNWUzYTQ4YTk5OWExNzE3YTkxOTg5YWIzMWVjNjZjYzNlOGJiNTE4MGRkNTViMTYzNDIyOTI2NGFhZGI4MTZhZWQ0NjlmMTU4ZWFkNWIwNzBiM2Q1MTUwMmE3OGI1MWM0MTA5MDk2MmExY2E3MmM5YmUxNTA3MjA3YzNmNmZkNTA0ZDY5Mzg5NmFjZjIzMWM3Zg=='
}
count = 1
for i in range(1, 4):
    url = f'https://image.baidu.***/search/acjson?tn=resultjson_***&word=%E4%BB%93%E9%BC%A0&ie=utf-8&fp=result&fr=&ala=0&applid=8444228557252761419&pn={i*30}&rn=30&nojc=0&gsm=3c&newReq=1'
    res = requests.get(url, headers=headers)
    dict_data = res.json()
    data_list = dict_data.get('data').get('images')
    for j in data_list:
        img_url = j.get('thumburl')
        # print(img_url)
        img_data = requests.get(img_url)
        byt_img_content = img_data.content
        with open(f'多页爬取图片/仓鼠{count}.png', 'wb') as f:
            f.write(byt_img_content)
        count += 1

爬出来的图片随便打开几个试试,能打开就是成功了

成功了,嘿嘿

转载请说明出处内容投诉
CSS教程网 » 认识爬虫(HTTP/HTTPS、会话技术、Proxy代理)

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买