Python学习-Python自带的爬虫模块常用知识点整理和应用场景

1、urllib.request模块

urllib.request模块是Python自带的模块,一些企业的老项目可能会用到该模块,所以我们有必要去了解这个模块。

1.1 版本

Python2版本会区分urllib2和urllib,但是到了Python3版本已经不做区分了,用的都是urllib.request。

1.2 常用的方法

  • urllib.request.urlopen(‘网址’)
    该方法的作用是向网站发起一个请求并获取响应对象,一般赋值 response = urllib.request.urlopen(‘网址’)。
  • response.read()
    该方法得到的是字节流(byte)数据,因此需要对其进行解码。
  • response.read().decode(‘utf-8’)
    对字节流数据进行解码,返回的是字符串类型的数据
  • urllib.request.Request(‘网址’,headers=‘字典’)
    该方法与urlopen()方法的作用一样,区别在于urlopen()方法不支持重构headers(即User-Agent),urllib.request.Request()方法是支持的。

1.3 响应对象常用的方法

  • read():读取服务器响应的内容
  • getcode():返回HTTP的响应码
  • geturl():返回实际数据的URL(防止重定向问题)

首先我们来看一下为什么要了解urllib模块,因为这个模块有自己的独特之处
对比一下:
(1)先用第三方库的requests模块在百度网站爬取一张图片

import requests
url1 = 'https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg'
response = requests.get(url1)
print(response)	# 返回表示请求成功
# 下面开始保存数据,有两种方式
# 方式一:
a = open('11.png','wb')		# 打开文件,并以二进制写入
a.write(response.content)	# 将网页请求返回的二进制数据(content内容)写到文件中
a.close()	# 关闭文件
# 方式二:
with open('22.png','wb') as file:
	file.write(response.content)

(2)再用urllib的request模块获取相同的数据

from urllib import request
url2 = 'https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg'
request.urlretrieve(url2,'33.png')

可以看到第二种方式的代码量明显少一些,这是因为urllib模块的request.urlretrieve方法里封装了包括文件的打开、写入等很多操作方法,不需要我们另外书写。

下面让我们来看一下urllib.request模块的一些使用情境:
(1)获取网站 https://qq.yh31.com/zjbq/2920180.html 的网页源码

import urllib.request
# 向网站发起一个请求,并得到一个响应结果对象,一般用一个变量接收
response = urllib.request.urlopen('https://qq.yh31.com/zjbq/2920180.html')
print(response)	# 结果是一个响应对象:
# 从响应对象中获取数据:用read()函数来读取数据
html = response.read()	# 返回字节流数据
print(type(html))	# 
# 对字节流数据进行解码(一般用utf-8)
html1 = html.decode('utf-8')
print(type(html1),html1)	# 返回结果: + 网页源码数据

(2)对于百度这类网页,需要用urllib.request.Request(‘网址’,headers=‘字典’)重构headers,才能请求到百度的网页源码

import urllib.request
url = 'https://www.baidu.com/'
# 构建请求头headers,即用户代理 User-Agent
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
# 第一步,创建请求对象
response = urllib.request.Request(url,headers=headers)
# 第二步,获取响应对象:urlopen()
obj = urllib.request.urlopen(response)
print(obj.getcode())	# 返回网页状态码 200,表示请求成功
print(obj.geturl())		# 返回实际请求的网站 https://www.baidu.com/
# 第三步,读取响应对象的内容:read().decode('utf-8')
html = obj.read().decode('utf-8')
print(html)

2、urllib.parse模块(一般要与urllib.request模块配合使用)

常用方法

  • urlencode(字典):对字典的值进行编码
  • quote(字符串):作用和urlencode(字典),不同的是该方法的参数要求是字符串类型

首先我们看一个现象:
在百度搜索海贼王,然后把带搜索关键字的url拿过来,
url = ‘https://www.baidu.com/s?wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B’
可以发现 wd等于一串带%(三个%区域组成一个汉字)的十六进制的ASCII码,这是因为网页不识别中文,传输的是ASCII码,因此需要我们手动将中文编码为ASCII码

import urllib.parse
r = {'wd':'海贼王'}
result = urllib.parse.urlencode(r)
print(result)

执行结果为:wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B,发现和上面的ASCII码内容是一样的。

下面我们做个练习:
在百度上输入一个内容,例如:海贼王,然后把网页数据保存到本地文件夹中,并命名为海贼王.html

import urllib.requests
import urllib.parse
# 关键字前面的基础网页
baseurl = 'https://www.baidu.com/s?'
content = input('请输入搜索内容:\n')	# 要输入的内容
wd = {'wd':content}
result = urllib.parse.urlencode(wd)
# 开始拼接url
url = baseurl + result
print(url)		# 结果为:https://wwww.baidu.com/s?wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B
# 加入请求头,以免被反爬
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
# 第一步:创建请求对象
response = urllib.request.Request(url,headers=headers)
# 第二步:获取相应对象
obj = urllib.request.urlopen(response)
# 第三步:读取响应对象的内容,并对其进行编码(防止有乱码出现)
html = obj.read().decode('utf-8')
# 第四步:保存文件
with open('海贼王.html','w') as file:
	file.write(html)

用quote(字符串)方法也可以实现上面urllib.parse.urlencode(‘字典’)方法相同的效果:

import urllib.request
key_word = input('请输入搜索内容:\n')
baseurl = 'https://wwww.baidu.com/s?wd='
r = urllib.parse.quote(key_word)
url = baseurl + r
print(url)	# 结果相同,为:https://wwww.baidu.com/s?wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B

3、常见的两种请求方式

  • get方式的特点:查询参数直接在URL地址中显示
  • post方式的特点:
    (1)需要在Request方法中添加data参数,即urllib.request.Request(url,data=data,headers=headers)
    (2)data:即表单数据,必须以bytes类型提交,不能是字符串。

(具体应用看接下来的两篇博客:百度贴吧练习有道翻译实现post请求

你可能感兴趣的:(Python学习,python)