scrapy分页抓取网页(2.3、Getamp常见的请求方法有两种(组图))
优采云 发布时间: 2022-02-18 09:07scrapy分页抓取网页(2.3、Getamp常见的请求方法有两种(组图))
HTTPS 的安全基础是 SSL,所以通过它传输的内容是经过 SSL 加密的。它的主要功能可以分为两种。
2.3、获取并发布
有两种常见的请求方法:GET 和 POST。
直接在浏览器中输入URL回车,发起GET请求,请求的参数会直接收录在URL中。比如在百度搜索Python,这是一个GET请求,链接为/s?wd=Python,其中url收录请求的参数信息,其中参数wd代表要搜索的关键字。 GET 请求正文为空。 POST 请求主要是在提交表单时发出的。比如登录表单,输入用户名和密码后,点击“登录”按钮,一般会发起POST请求,数据一般以表单的形式传输,不体现在URL中。
GET 和 POST 请求方法有以下区别。
一般来说,登录时需要提交用户名和密码,其中收录敏感信息。如果使用 GET 方式请求,会在 URL 中暴露密码,导致密码泄露,所以最好通过 POST 发送。上传文件时,由于文件内容比较大,也使用POST方式。
2.4、爬虫定义
简单来说,爬虫是一个自动程序,它获取网页并提取和保存信息。
最关键的部分是构造一个请求并将其发送到服务器,然后接收并解析响应。
2.5、会话和 Cookie
HTTP的无状态意味着HTTP协议没有用于事务处理的内存能力,这意味着服务器不知道客户端处于什么状态。当我们向服务器发送请求时,服务器会解析请求,然后返回相应的响应。服务器负责完成这个过程,这个过程是完全独立的。服务器不会记录前后状态的变化,即缺少状态记录。这意味着如果前面的信息需要在后面进行处理,就必须重传,这就导致需要通过一些额外的前面的重复请求才能获得后续的响应,但是这样的效果显然不是我们想要的。为了保持前后的状态,千万不能把之前所有的请求都重传一次,这样太浪费资源了,对于这种需要用户登录的页面更是难上加难。
有两种技术可用于维护 HTTP 连接的状态,会话和 cookie。 session在服务端,即网站的服务端,用来保存用户的session信息;客户端的cookies也可以理解为浏览器端。使用 cookie,浏览器会自动将其附加到下一页访问。发送到服务器后,服务器通过识别Cookies来识别用户,进而判断用户是否处于登录状态,然后返回相应的响应。
我们可以理解,登录凭据存储在 cookie 中。有了它,您只需在下一次请求中发送带有cookies的请求,无需重新输入用户名、密码等信息再次登录。
2.5.1、常见误区
在谈论会话机制时会听到一个常见的误解 - “一旦关闭浏览器,会话就会消失”。想象一下会员卡的例子。除非顾客主动要求店家注销卡,否则店家绝不会轻易删除顾客的资料。会话也是如此,除非程序告诉服务器删除会话,否则服务器会保留它。比如我们在进行注销操作时,程序一般会删除会话。
但是当我们关闭浏览器时,浏览器并没有在关闭前主动通知服务器即将关闭,所以服务器根本没有机会知道浏览器已经关闭。产生这种错觉的原因是大部分会话机制使用会话cookie来保存会话ID信息,而cookie在关闭浏览器后消失。再次连接服务器时,找不到原来的会话。如果服务器设置的cookies保存到硬盘,或者浏览器发送的HTTP请求头通过某种方式被改写,将原来的cookies发送给服务器,那么可以再次打开浏览器,原来的会话ID仍然可以找到,仍然可以维护。登录状态。
而正是因为关闭浏览器不会导致会话被删除,这就需要服务器为会话设置一个过期时间。当自客户端上次使用会话以来的时间超过此过期时间时,服务器可以考虑在活动停止时删除客户端会话以节省存储空间。
3、基本操作
# 普通 GET 请求
response = urllib.request.urlopen('https://www.python.org')
print(response.read().decode('utf-8'))
# POST 请求
# 这里我们传递了一个参数 word, 值是 hello, 它需要被转码成 bytes(字节流)类型
# 而转字节流采用了 bytes 方法,该方法的第一个参数需要是 str(字符串)类型
data = bytes(urllib.parse.urlencode({'word' : 'hello'}), encoding = 'utf8')
# 还有 timeout 设置超时参数
# cafile 和 capath 这两个参数分别指定 CA 证书和它的路径
response = urllib.request.urlopen('http://httpbin.org/post', data = data)
# request 更多的控制参数
# headers 参数通常是设置 User-Agent 来伪装浏览器
# method 代表 GET、POST 等
urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
3.1、高级操作
# urllib.request 模块里的 BaseHandler 类可以处理 Cookies 等高级操作
# 比如下图的需要身份验证
from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
from urllib.error import URLError
username = username
password = 'password'
url = 'http://localhost:5000/'
p = HTTPPasswordMgrWithDefaultRealm()
p.add_password(None, url, username, password)
auth_handler = HTTPBasicAuthHandler(p)
opener = build_opener(auth_handler)
try:
result = opener.open(url)
html = result.read().decode('utf8')
print(html)
except URLError as e:
print(e.reason)
# 设置代理
proxy_handler = ProxyHandler({
'http' : 'http://127.0.0.1:9743',
'https': 'https://127.0.0.1:9743'
})
opener = build_opener(proxy_handler)
# 设置 Cookies
cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
# request 库设置 Cookies,request 库可以直接把 Cookie 参数放到 headers 里
r = requests.get('https://www.baidu.com')
# 从中可以看出 Cookie 的类型
print(r.cookies)
for key, value in r.cookies.items():
print(key + '=' + value)
# urlparse() 可以实现 URL 的识别和分段
# quote() 可以将中文字符串转化为 URL 编码
# 对应 unquote() 就是反过来
# 身份验证
r = requests.get('http://localhost:5000', auth=('username', 'password'))
3.1.1、处理二进制数据
# 下载文件
import requests
r = requests.get('https://github.com/favicon.ic')
with open('favicon.ico', 'wb') as f:
f.write(r.content)
# 上传文件
files = {'file' : open('favicon.ico', 'rb')}
r = requests.post('http://httpbin.org/post', files=files)
3.2、机器人协议
Robots 协议也称为爬虫协议和机器人协议。它的全称是Robots Exclusion Protocol,用于告诉爬虫和搜索引擎哪些页面可以爬取,哪些页面不能爬取。它通常是一个名为 robots.txt 的文本文件,通常放在 网站 的根目录下。
搜索爬虫访问网站时,首先会检查网站根目录下是否有robots.txt文件。如果存在,搜索爬虫将根据其中定义的爬取范围进行爬取。如果没有找到该文件,搜索爬虫将访问所有可直接访问的页面。
User-agent: *
Disallow: /
Allow: /public/
上述案例的文件内容表示所有搜索爬虫只允许爬取公共目录。
User-agent用于设置爬虫的名称,*表示适用于所有。
disallow代表不能爬取的目录,/代表禁止爬取所有页面。
# 传入 robots.txt 文件的链接即可解析
urllib.robotparser.RobotFileParser(url='')
print(rp.can_fetch('*', 'http://www.jianshu.com/p/b67554025d7d'))
3.3、会话维护
在请求中,如果直接使用get或post等方法,确实可以模拟网页请求,但这实际上相当于不同的会话,也就是说你使用两个浏览器打开不同的页面。
想象这样一个场景,第一次请求使用post方法登录某个网站,第二次登录成功后想获取自己的个人信息,再次使用get方法请求个人信息页面。其实这相当于打开了两个浏览器,两个完全不相关的会话。能否成功获取个人信息?当然不是。
你们中的一些人可能说过我可以为两个请求设置相同的 cookie,对吧?是的,但是这样做很麻烦,而且我们有一个更简单的解决方案。
其实这个问题的主要解决方案是保持同一个会话,相当于打开一个新的浏览器标签而不是打开一个新的浏览器。但是我不想每次都设置cookies,我该怎么办?这时候就有了新的武器——Session对象。
s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789')
r = s.get('http://httpbin.org/cookies')
3.4、使用代理
对于一些网站,在测试过程中多次请求后可以正常获取内容。但是一旦开始*敏*感*词*爬取,对于*敏*感*词*频繁的请求,网站可能会弹出验证码,或者跳转到登录认证页面,甚至直接屏蔽客户端IP,造成一定的周期的时间。内部无法访问。
import requests
proxies = {
"http" : "http://10.10.1.10:3128",
"https" : "http://10.10.1.10:1080",
}
requests.get("https://www.taobao.com", proxies=proxies)
4、动态渲染数据爬取
有时当我们抓取带有请求的页面时,结果可能与我们在浏览器中看到的不同:
在浏览器中可以看到页面数据正常显示,但是使用requests得到的结果却不是。这是因为请求都是原创的 HTML 文档,而浏览器中的页面是通过 JavaScript 处理数据的结果。这些数据有多种来源,可以通过 Ajax 加载或收录在 HTML 中。在文档中,也可能是由 JavaScript 和特定算法生成的。
对于第一种情况,数据加载是一种异步加载方式。最初的页面不会收录一些数据。原创页面加载完成后,会向服务器请求一个接口获取数据,然后再加载数据。处理并渲染到网页,其实就是发送一个ajax请求。
根据Web的发展趋势,这种形式的页面越来越多。网页的原创HTML文档不收录任何数据,数据通过Ajax统一加载后显示,这样在Web开发中可以分离前后端,以及服务器带来的压力减少直接渲染页面。
所以遇到这样的页面,直接使用requests等库抓取原创页面是无法获取有效数据的。这时候就需要分析网页后端向接口发送的Ajax请求了。如果可以使用requests来模拟ajax请求,那么就可以成功爬取了。
4.1、Ajax 定义
Ajax,全称是Asynchronous JavaScript and XML,即异步JavaScript XML,它不是一种编程语言,而是使用JavaScript与服务器交换数据,更新一些网页而不刷新页面和页面链接不变。技术。
对于一个传统的网页,如果要更新它的内容,就必须刷新整个页面,但是使用Ajax,你可以在不刷新整个页面的情况下更新页面的内容。在这个过程中,页面实际上是在后台与服务器交互的。获取到数据后,通过JavaScript来改变网页,从而更新网页的内容。
4.2、Ajax 数据抓取
向网页更新发送Ajax请求的过程可以分为以下几个步骤:
1、发送请求
2、解析内容
3、渲染网页
通过开发者模式找到类型为XHR的请求,查看请求的url和请求体,并进行模拟。
并非所有页面都可以通过分析 Ajax 进行爬取。有些页面的参数比较复杂,可能收录加密密钥。很难自己构造参数。
通过直接模拟浏览器操作,无需关注这些界面参数。
4.3、页面动态渲染
但是,javaScript 动态呈现的页面并不局限于 Ajax。有些网页的分页部分是由 JavaScript 生成的,而不是原创的 HTML 代码,不收录 Ajax 请求。比如ECharts的官方实例,它的图形都是JavaScript计算后生成的。
为了解决这些问题,我们可以直接使用模拟浏览器操作的方式,这样就可以看到浏览器里面有什么,抓取到什么源码,也就是什么时候可以抓取它是可见的。 这样,我们就不再需要关心网页内部的 JavaScript 使用什么算法来渲染页面,也不需要关心网页后台的 Ajax 接口的参数。