对爬虫中基本库的使用方法进行归纳和总结
1.urllib
首先介绍一个库urllib,利用python中的urllib库,我们可以通过指定URL,请求头,请求体等来实现所需http请求的发送,并且可以将服务器返回的响应转换为python对象,进而更方便的获取响应信息。
1.1请求(request)
1.1.1直接通过urlopen函数
response = urllib.request.urlopen(url,data=None,timeout,cafile=None,capath=None,cadefault=False,context=None)
urllib提供了一个最基本的构造http请求的方法,其中:
url是请求的URL,也是该方法唯一的必需参数,剩下的都是可选参数
利用最基本的urllib方法可以进行对网页的GET请求抓取。
1.通过URL参数
举例如下:
import urllib.request
from pprint import pprint#美化输出模块
# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
def main():
response = urllib.request.urlopen("https://www.baidu.com/")
pprint(response.getheaders())
pprint(response.read())
pprint(type(response))
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
main()
print("获取网页源代码成功")
对www.baidu.com进行爬取,其得到的输出内容如下:
输出请求头
[('Accept-Ranges', 'bytes'),
('Cache-Control', 'no-cache'),
('Content-Length', '227'),
('Content-Security-Policy',
"frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com "
'https://fj-chat.baidu.com https://hba-chat.baidu.com '
'https://hbe-chat.baidu.com https://njjs-chat.baidu.com '
'https://nj-chat.baidu.com https://hna-chat.baidu.com '
'https://hnb-chat.baidu.com http://debug.baidu-int.com;'),
('Content-Type', 'text/html'),
('Date', 'Sat, 30 Mar 2024 14:46:40 GMT'),
('Pragma', 'no-cache'),
('Server', 'BWS/1.1'),
('Set-Cookie', 'BD_NOT_HTTPS=1; path=/; Max-Age=300'),
('Set-Cookie',
'PSTM=1711810000; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; '
'path=/; domain=.baidu.com'),
('Set-Cookie',
'H_PS_PSSID=40169_40080_40373_40368_40398_40416_40309_40459_40481_39662_40514_40446_60041_60030_40510; '
'path=/; expires=Sun, 30-Mar-25 14:46:40 GMT; domain=.baidu.com'),
('Set-Cookie',
'BAIDUID=A42F16C36B56F67916E9DCCE5F8616FF:FG=1; Path=/; Domain=baidu.com; '
'Max-Age=31536000'),
('Set-Cookie',
'BAIDUID_BFESS=A42F16C36B56F67916E9DCCE5F8616FF:FG=1; Path=/; '
'Domain=baidu.com; Max-Age=31536000; Secure; SameSite=None'),
('Traceid', '1711810000364990695416469053921881009841'),
('X-Ua-Compatible', 'IE=Edge,chrome=1'),
('X-Xss-Protection', '1;mode=block'),
('Connection', 'close')]
输出网页源码
(b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.repl'
b'ace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<nosc'
b'ript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></nosc'
b'ript>\r\n</body>\r\n</html>')
输出返回类型
<class 'http.client.HTTPResponse'>
由此可以看出通过请求返回的response对象的类型是HTTPResponse
该对象包含了几种常用的方法和属性,其中有:
read()获取网页源码
getheader(str)获取请求头的某一项
getheaders()获取全部请求头
msg,version,status,reason,debuglevel,closed等属性
2.使用data参数
添加data参数可以向目标网站传递参数,此时请求模式不再是GET而是POST
注意:添加参数时需要将data转化为bytes类型
def main():
data = bytes(urllib.parse.urlencode({'name':'germey'}),encoding='utf-8')#urlencode方法将字典参数转化为字符串,再用utf-8编码
response = urllib.request.urlopen('https://www.httpbin.org/post',data=data)
print(response.read().decode('utf-8'))
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
main()
print("获取网页源代码成功")
输出结果如下:
{
"args": {},
"data": "",
"files": {},
"form": {
"name": "germey"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "11",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "www.httpbin.org",
"User-Agent": "Python-urllib/3.10",
"X-Amzn-Trace-Id": "Root=1-66082eda-1365c31c6515444a1f883304"
},
"json": null,
"origin": "42.234.23.197",
"url": "https://www.httpbin.org/post"
}
从form字段中发现了germey,这表明是在以POST方式传递数据
3.使用timeout参数
timeout参数意为设置超时时间,单位为秒,如果请求超出了这个时间还没有收到响应,就会抛出异常。如果不设置该参数,则会使用全局默认时间,这个参数支持http,https和ftp协议。
def main():
response = urllib.request.urlopen('https://www.httpbin.org/get',timeout=0.1)
print(response.read())
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
main()
print("获取网页源代码成功")
设置timeout为0.1,抛出URLError超时异常
也可以利用try-except进行异常处理
def main():
try:
response = urllib.request.urlopen('https://www.httpbin.org/get',timeout=0.1)
except urllib.error.URLError as e:
if isinstance(e.reason,socket.timeout):
print('time out......')
1.1.2通过Request
如果需要向请求中加入请求头,那么直接通过urlopen显然是不够用的,于是我们就可以用Request类来构建含有更多信息的请求头
具体方法如下:
class.urllib.request.Request(url,data=None,headers={},origin_req_host=None,method=None,unverifiable=False)
1.URL必选参数,用于请求URL
2.上传data参数,必需为bytes类型,如果数据是字典必需使用parse模块的urlencode方法进行编码
3.headers是一个字典,也就是请求头,可以直接构造也可以请求方法添加
4.是指请求方的host地址或者IP地址
5.method表示请求方法,如GET,POST,PUT
6.表示用户有没有足够的权限来接收响应,例如请求网页中的图片,但没有抓取图片的权限,那么该值设为True
传入多个参数构建Request类
def main():
url = 'https://www.httpbin.org/post'
headers = {
'User-Agent':'Mozilla/4.0(compatible;MSIE 5.5;Windows NT)',
'Host':'www.httpbin.org'
}
dict = {'name':'germey'}
data = bytes(parse.urlencode(dict),encoding='utf-8')
req = request.Request(url=url,data=data,headers=headers,method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
main()
print("获取网页源代码成功")
返回结果如下:
{
"args": {},
"data": "",
"files": {},
"form": {
"name": "germey"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "11",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "www.httpbin.org",
"User-Agent": "Mozilla/4.0(compatible;MSIE 5.5;Windows NT)",
"X-Amzn-Trace-Id": "Root=1-66083875-0ddb23e34425ee743ece6bcb"
},
"json": null,
"origin": "42.234.23.197",
"url": "https://www.httpbin.org/post"
}
从返回结果可知,成功设置了data,headers和method
其中对User-Agent的设置通常是为了伪装浏览器。从上图可知我们成功伪装成了浏览器对网站进行访问
1.1.3验证,代理和cookie用法
待续......