爬虫----request模块

urllib模块:

        urllib 库 是 Python 内置的 HTTP 请求库。urllib 模块提供的上层接口,使访问 www 以及 ftp 上的数据就像访问本地文件一样。 有以下几种模块:

  • urllib.request 请求模块

  • urllib.error 异常处理模块

  • urllib.parse url解析模块

  • urllib.robotparser robots.txt 解析模块

urllib.request模块详讲:

        urllib.request 模块提供了最基本的构造 HTTP 请求的方法,利用它可以模拟浏览器的一个请求发起过程,同时它还带有处理 authenticaton (授权验证), redirections (重定向), cookies (浏览器Cookies)以及其它内容。

常用的方法

  • urllib.request.urlopen("网址"/"请求对象")  作用 :向网站发起一个请求并获取响应(urlopen不支持user-agent,因此只能爬取一些简单的网站)

  • read()  读取服务器响应的内容

  • 字节流 = response.read()         -----  内容为字节数据

  • 字符串 = response.read().decode("utf-8")      ------ 将字节流解码成utf-8格式

  • getcode() 返回HTTP的响应码

  • geturl()  返回实际数据的URL(防止重定向问题)

  • urllib.request.Request("网址",headers="字典")

urllib.request.urlopen("网址"/"请求对象")实例(以百度网站为例):

首先打开开发者工具(按F12)然后找到Network(网络),找到其网址以及请求方法。

 

 User-Agent 就是我们常说的请求头,我们在做爬虫伪装时需要它。(在标头往下面划就能看到)

 由于urlopen这个函数并没有headers这个参数,因此我们在进行参数传递时不能将其加入。

import urllib.request
# 目标url
url = "http://www.baidu.com"
# 请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}
# 发起请求
response = urllib.request.urlopen(url)

# 获取响应
# text = response.read()  # 获取字节流
text = response.read().decode('utf-8')  # 获取字符串
# print(text)

print(response.getcode())  # 返回HTTP的响应码
print(response.geturl())   # 返回实际数据的URL

urllib.request.Request("网址","请求头")实例:

        由上我们知道利用 urlopen() 方法可以实现最基本的请求发起,但这几个简单的参数并不足以构建一个完整的请求,如果请求中需要加入 headers 等信息,我们就可以利用更强大的 Request 类来构建一个请求。

import urllib.request

url = "http://www.baidu.com"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

# 1 创建请求对象并构建User-Agent
req = urllib.request.Request(url, headers=headers)
print(req)  # <urllib.request.Request object at 0x000001B411D38048> 请求对象
# 2获取响应对象  urlopen
"""
我们依然是用urlopen()方法来发送这个请求,只不过这次urlopen()方法的参数不再是一个URL,
而是一个Request,通过构造这个这个数据结构,
一方面我们可以将请求独立成一个对象,另一方面可配置参数更加丰富和灵活。
"""
response = urllib.request.urlopen(req)
# 3读取响应对象的内容  read().decode("utf-8")
html = response.read().decode("utf-8")
print(html)

urllib.parse模块详讲:

常用方法

  • urlencode(字典)

  • quote(字符串) (这个里面的参数是个字符串)

        我们在爬取网页的时候,会遇到网址里面的参数出现中文,由于我们的计算机只能识别ACILL码,而中文并不在里面,因此我们需要将中文转为计算机能够识别的形式。就比如我们将下面这个网址直接在Pycharm里面复制是这样的效果:

        我们可以发现在Pycharm里面我们并没有看到美女这个字眼,而是一些我们看不懂的字母和数字,其实那些组合在一起就是美女。

​
url1 = "https://tieba.baidu.com/f?ie=utf-8&kw=%E7%BE%8E%E5%A5%B3&fr=search"
url2 = "https://tieba.baidu.com/f?ie=utf-8&kw=美女&fr=search"

req = urllib.request.urlopen(url1)
print(req)  # UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-12: ordinal not in range(128)

req = urllib.request.urlopen(url2)
print(req)

​

 第一个它正常给我们打印了一个响应对象:

 第二个它给我们报了一个错误:UnicodeEncodeError: 'ascii' codec can't encode characters in position 19-20: ordinal not in range(128)

这个错误就是因为中文不在这128个ASCILL码里面,所以我们的参数里面不能有中文,需要将其转为计算机能够识别的形式。

# 第一种方法
'''
urlencode
传入参数类型:字典
功能:将存入的字典参数编码为URL查询字符串,即转换成以key1=value1&key2=value2的形式
导入:from urllib.parse import urlencode
'''
r = {"ie": "美女"}
result = urllib.parse.urlencode(r)  # 对r进行解码
print(result)
f_url = "https://www.baidu.com/s?" + result + '&fr=search'
print(f_url)
# 第二种方法
'''
urlencode
传入参数类型:字典
功能:将存入的字典参数编码为URL查询字符串,即转换成以key1=value1&key2=value2的形式
导入:from urllib.parse import urlencode
'''
r = {"ie": "美女"}
result = urllib.parse.urlencode(r)  # 对r进行解码
print(result)
f_url = "https://www.baidu.com/s?" + result + '&fr=search'
print(f_url)

urllib保存图片实例分析:

print()
"""
urllib方法
参数说明:
url:外部或者本地url
filename:指定了保存到本地的路径(如果未指定该参数,urllib会生成一个临时文件来保存数据);
reporthook:是一个回调函数,我们可以利用这个回调函数来显示当前的下载进度。
data:指post到服务器的数据。该方法返回一个包含两个元素的元组(filename,headers),filename表示保存到本地的路径,header表示服务器的响应头。
"""
from urllib import request
from urllib.request import urlretrieve

url = "https://xinzhuobu.com/wp-content/uploads/2023/04/20230409003.jpg"
# 本地下载,文件名为1.jpg
request.urlretrieve(url=url, filename="1.jpg")

Requests模块

Requests简介

        Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。

  • Beautiful is better than ugly.(美丽优于丑陋)

  • Explicit is better than implicit.(清楚优于含糊)

  • Simple is better than complex.(简单优于复杂)

  • Complex is better than complicated.(复杂优于繁琐)

  • Readability counts.(重要的是可读性)

Requests模块的安装

Requests是Python语言的第三方的库,专门用于发送HTTP请求 安装方式

  • pip install requests

  • 在开发工具中安装

可以使用下面的下载镜像,这样下载速度会快一点。

# 阿里云 http://mirrors.aliyun.com/pypi/simple/
# 豆瓣http://pypi.douban.com/simple/
# 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
# 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
# 华中科技大学http://pypi.hustunique.com/

下载方式:pip install requests 后面接你选择的镜像

Requests的使用:

Requests常用方法(我们一般通过开发者工具判断这个网址应该使用什么方法)

  • requests.get("网址")

  • request.post("网址")

  • put、delete等等method不常用 

Requests常用参数:

        url 请求的: url 地址 接口文档标注的接口请求地址 params:请求数据中的链接,常见的一个 get 请求,请求参数都是在 url 地址中 data :请求数据,参数 表单的数据格式 json: 接口常见的数据请求格式 headers:请求头信息,http 请求中,比如说编码方式等内容添加 cookie:保存的用户登录信息,比如做一些充值功能,但是需要用户已经登录,需要 cookie信息的请求信息传输

Requests响应内容r.encoding 获取当前的编码

r.encoding = 'utf-8':设置编码为utf-8格式

r.text:以encoding解析返回内容。字符串方式的响应体,会自动根据响应头部的字符编码进行解码。

r.cookies: 返回cookie

r.headers :以字典对象存储服务器响应头

r.status_code: 响应状态码

r.json() :Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的,不然解析出错会抛异常 r.content 以字节形式(二进制)返回。字节方式的响应体,会自动为你解码。

 

Requests中get请求之参数应用:

第一种: 把参数添加到url链接中:

import requests
url = 'https://www.sogou.com/web?query=%E6%B5%B7%E8%B4%BC%E7%8E%8B&_asf=www.sogou.com&_ast=&w=01015002&p=40040108&ie=utf8&from=index-nologin&s_from=index&oq=&ri=0&sourceid=sugg&suguuid=&sut=0&sst0=1678439364372&lkt=0%2C0%2C0&sugsuv=1666847250696567&sugtime=1678439364372'
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}
html = requests.get(url, headers=headers).text
print(html)

第二种:把参数添加到params中

注意点: params的数据类型为字典数据,同样必须满足键值对

import requests
url = 'https://www.sogou.com/web'
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
parmas = {
    "query": "美女",
    "_asf": "www.sogou.com",
    "_ast": "w: 01015002",
    "p": "40040108",
    "ie": "utf8",
    "from": "index-nologin",
    "s_from": "index",
    "oq": "ri: 0",
    "sourceid": "sugg",
    "suguuid": "sut: 0",
    "sst0": "1678439364372",
    "lkt": "0,0,0",
    "sugsuv": "1666847250696567",
    "sugtime": "1678439364372",
}
html = requests.get(url, headers=headers, params=parmas).text
print(html)

扩展:快速将headers中的参数匹配为字典数据:

1. 首先在pycharm里面建立一个文本文件

2. 将参数复制进去

3,先ctrl+A全选,然后ctrl+R

4.在第一行输入 (.*?): (.*?)       注意我这边是有一个空格的,因为可以看到冒号右边是有一个空格,所以需要添加(根据不同情况做不同处理)

在第二行输入'$1':‘$2’,然后点击replace all即可

 其实懂正则的朋友一下就看出来了,这里就是将每一个字符串加一个引号,也可以手动添加,但是如果参数多的话手动添加就麻烦了。

Requests中post请求

requests请求方法除了get请求方法外,还有其他方法,比如常用的post方法 什么场景下需要用到post方法呢?

  1. 网页需要登录的情况下;

  2. 需要给网页传输内容的情况下。

其实用法大都数和get请求一样,只是需要加上data参数 语法格式

response = requests.post("http://www.baidu.com/", data = data,headers=headers)

 这里的data就是表单信息,我们使用data必须将其表单参数传递进入(以百度翻译为例子):

 data的数据类型是一个字典,因此我们需要将所有的键值对放入data中然后通过post传递。

下面我用360翻译给大家做个实例:

首先我们需要在开发中工具中找到需求的url,那我们应该如何确定呢?

第一:我们先查看源代码进行观察:

我们可以发现源代码里面的信息很少,貌似并没有我们需要的内容。这个时候我们猜想这个网址是否是Ajax加载。

我们打开我们的开发者工具,然后选择Fetch/XHR(这个就是用来查看动态页面的):

我们在输入框里面输入’你好‘然后点击翻译,我们可以发现此时里面多了一个内容:

其实这个内容就是我们要找的那一个,只是如果你觉得这样太草率了,这样并不能保证就是这个,那这个时候我们点击这个内容进行查看(将那个节点(小三角形)一个一个展开):我们可以发现里面就有“你好‘,以及其翻译的‘Hello’。

 找到内容后我们就可以对该网址进行一个爬取啦:

找到网址,请求方法以及请求头(大家不要被我这个误导,一般的请求头加一个User-Agent就够了,而这个翻译的反爬需要我们加更多的伪装才行获取内容):

 

 发现它是post请求,则到载荷里面查找其data

 我们在预览里面可以发现它是一个类似字典的数据类型,但是网页里面存储的是字符串,因此它是一个json字符串类型,我们可以通过json的方法loads将其转化为字典,然后通过字典索引的方式找到我们需要的内容。

 代码展示:

import requests
import json

url = 'https://fanyi.so.com/index/search?eng=0&validate=&ignore_trans=0&query=%E4%BD%A0%E5%A5%BD'
headers={
    "pro": "fanyi",
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}

data = {
    "eng": "0",
    "validate": "",
    "ignore_trans": "0",
    "query": "你好"
}

response = requests.post(url,headers=headers,data=data)
response.encoding = 'utf-8'
# print(response.text)
# print(type(response.text))
content = json.loads(response.text)
print(content['data']['fanyi'])

 

Cookie与Session实战

在浏览网站的过程中,我们经常会遇到需要登录的情况,有些页面只有登录之后才可以访问。在登录之后可以连续访问很多次网站,但是有时候过一段时间就需要重新登录。还有一些网站,在打开浏览器时就自动登录了,而且在很长时间内都不会失效,这又是什么情况?其实这里面涉及 Session 和Cookie 的相关知识,本节就来揭开它们的神秘面纱。

概念

Cookie

通过在客户端记录的信息确定用户身份 HTTP是一种无连接协议,客户端和服务器交互仅仅限于 请求/响应过程,结束后断开,下一次请求时,服务器会认为是一个新的客户端,为了维护他们之间的连接,让服务器知道这是前一个用户发起的请求,必须在一个地方保存客户端信息。

Session

Session,中文称之为会话,通过在服务端记录的信息确定用户身份 这里这个session就是一个指的是会话。其本义是指有始有终的一系列动作、消息。例如打电话时,从拿起电话拨号到挂断电话之间的一系列过程就可以称为一个 Session。

这样做有什么好处?

最大的好处就是用户只需要输入一次账号密码,之后再访问网页时,只需要再Headers信息利用Cookie包含Session_id,后台就可以根据Session_id来判断用户是否登录。

 我们在爬取一些需要登录才能获取内容的网站,比如淘宝,大众点评等,这个时候我们就需要将cookie也作为参数传递到我们的请求方法中去。

 以大众点评为例(首先你需要将你的账号先登录),通过标头里面的cookie我们可以找到:

 

 将你的cookie用键值对的方式保存即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值