1.Python爬虫基本库的使用
1.1 学习使用urllib库
urllib库是Python内置的HTTP请求库之一(还有httplib2、requests、treq等),包含以下4个模块:
- request: 最基本的HTTP请求模块,用来模拟发送请求;
- error: 异常处理模块;
- parse: 一个工具模块,提供许多URL处理方法;
- robotparser: 主要用来识别网址的robots.txt文件,判断网站是否可以爬取(其实用的比较少);
1.1.1 发送请求(request模块)
a. urlopen()
1 | import urllib.request |
urlopen()的data参数:
1 | import urllib.request |
urlopen()的timeout参数:
1 | import urllib.request |
b. Request
urlopen()只能实现最基本的请求的发起,如果要构建完整的请求,就需要利用更强大的Request类在请求中加入Headers等信息。
1 | import urllib.request, parser |
c. 高级用法:Cookies处理、代理设置、登录验证等
urllib.request模块里的BaseHandler类(各种处理器)可以完成这些功能,现列出其常用子类:
- HTTPDefaultErrorHandler:处理HTTP响应错误,抛出HTTPError;
- HTTPRedirectHandler: 用于处理重定向;
- HTTPCookieProcessor: 用于处理Cookies;
- ProxyHandler: 用于设置代理,默认代理为空;
- HTTPPasswordMgr: 用于管理密码,维护了用户名和密码表;
- HTTPBasicAuthHandler: 用于管理认证,若一个连接打开时需要认证,则可用其解决认证问题;
打开需要身份验证的网站
1 | from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener,OpenerDirector |
代理设置
1 | from urllib.error import URLError |
Coockies处理
1 | import http.cookiejar,urllib.request |
1.1.2 处理异常(error模块)
防止网络不稳定不好的状况下,程序出现异常而停止运行。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30from urllib import request,error
import socket
#异常处理
url = 'https://cuiqingcai.com/index.htm'
try:
res = request.urlopen(url)
print(res.read().decode('utf-8'))
# HTTPError 是 URLError 的子类
except error.HTTPError as e:
print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
if isinstance(e.reason,socket.timeout):
print('timeout')
print(e.reason)
else:
print('request successfully')
# result:
g:\Python\Demon2\new_book\basic_lib>b8.py
Not Found
404
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 10 Jul 2018 05:58:21 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
Vary: Cookie
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Link: <https://cuiqingcai.com/wp-json/>; rel="https://api.w.org/"
1.1.3 解析连接(parse模块)
parse定义了处理URL的标准接口。
a. urlparse()
实现url的识别和分段,拆为6个部分:scheme、netloc、path、params、query、fragment1
2
3
4
5
6
7
8
9
10
11from urllib.parse import urlparse
url = 'https://www.baidu.com/index.html;user?id=5#comment'
result = urlparse(url,scheme='http',allow_fragments=True)
print(type(result)) #<class 'urllib.parse.ParseResult'>
print(result)
#ParseResult(scheme='https', netloc='www.baidu.com',
#path='/index.html', params='user', query='id=5', fragment='comment'
print(result.scheme, result.netloc, result.path, result.params,
result.query, result.fragment,sep = '\n')
print(result[0], result[1])# https www.baidu.com
b. urlunparse()
url组合,合并连接,接受的参数是一个可迭代对象(可以被遍历),且长度必须是6.1
2
3
4
5
6
7from urllib.parse import urlunparse
url_data = ['https','www.baidu.com','/index.html',
'user','id=5','comment']
url = urlunparse(url_data)
print(url)
#https://www.baidu.com/index.html;user?id=5#comment
c. urlsplit()
同urlparse()很像,只是拆解url时,少了params(合并到path中)这一部分1
2
3
4
5
6
7
8
9from urllib.parse import urlsplit
url2 = 'https://www.baidu.com/index.html;user?id=5#comment'
data = urlsplit(url2)
print(data)
#SplitResult(scheme='https', netloc='www.baidu.com',
# path='/index.html;user', query='id=5', fragment='comment')
print(data.netloc,data[1],end='\n')
# www.baidu.com www.baidu.com
d. urlunsplit()
同urlunparse()很像,传入参数也必须是一个可迭代对象,区别是长度必须为51
2
3
4
5
6
7from urllib.parse import urlunsplit
url_data2 = ['https','www.baidu.com','index.html',
'id=5','comment']
url3 = urlunsplit(url_data2)
print(url3)
# https://www.baidu.com/index.html?id=5#comment
e. urljoin()
也是将连接合并,接受两个参数,将第一个base_url(基础连接)作为第一个参数,新的连接作为第二个参数,该方法会分析base_url的scheme、netloc和path这三个内容,并对新连接缺失的内容进行补充,最后返回结果。
1 | from urllib.parse import urljoin |
可见,base_url 提供了3项内容scheme、netloc及path。当这3项在新连接里不存在时,就予以补充,新连接里有的话,就用新连接自己的;base_url中的params、query和fragment是不起作用的。
f. urlencode()
此方法在构造GET请求参数时非常有用,将字典类型的参数转化为GET请求的参数。1
2
3
4
5
6
7
8from urllib.parse import urlencode
query = {'name':'Jou','age':2}
query = urlencode(query)
print(query) # name=Jou&age=2
base_url = 'https://www.baidu.com?'
url = base_url + query
print(url) #https://www.baidu.com?name=Jou&age=2
g. parse_qs()与parse_qsl()
二者与urlencode()相反的功能:
1.parse_qs()将GET请求参数转化为字典类型;
2.parse_qsl()将GET请求参数转化为元组组成的列表;
1 | from urllib.parse import parse_qs, parse_qsl |
h.中文字符转URL编码与反转–qutoe()及unqutoe()
1 | from urllib.parse import quote,unquote |
1.1.4 Robots协议分析(robotparser模块)
也被称为爬虫协议、机器协议,全名叫网络爬虫排除标准,用来告诉爬虫和搜索引擎哪些页面可以爬取,哪些不可以爬取;
robotparser模块提供了一个类RobotFileParser,它可以根据某网站的robots.txt文件来判断一个爬虫是否有权限来爬取这个网页。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17from urllib.robotparser import RobotFileParser
# 创建一个RobotFileParser对象
rb = RobotFileParser()
url = 'http://www.jianshu.com/robots.txt'
url_fetch1 = 'http://www.jianshu.com/p/b67554025d7d'
url_fetch='http://www.jianshu.com/search?q=python&page=1&type=collections'
url2 = 'https://www.jianshu.com/'
# 接收robots.txt连接参数,判断是否有权限爬取
rb.set_url(url)
#读取robots.txt文件并分析
rb.read()
rbool = rb.can_fetch('*', url2)
r1bool = rb.can_fetch('*', url_fetch1)
r2bool = rb.can_fetch('*', url_fetch)
print(rbool) #False
print(r1bool) #False
print(r2bool) #False
1.2 requests库的使用
1.2.1 基本用法
1 | import requests |
GET()请求
1 | import requests |
知乎问题抓取:
1 | import requests |
github图标抓取
1 | import requests |
1.2.2 高级用法
a. 文件上传
1 | import requests |
b. Cookies
使用requests来使用设置Cookies都很简洁:
1.获取Cookie1
2
3
4
5
6
7
8
9
10
11
12
13import requests
url = 'https://www.baidu.com/'
r = requests.get(url)
cookies_baidu = r.cookies
print(cookies_baidu)
#<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
#利用items()方法将其转化为元组组成的列表,实现Cookie的遍历解析
print(cookies_baidu.items()) # [('BDORZ', '27315')]
for key,value in cookies_baidu.items():
print(key+':'+value)
#BDORZ:27315
- 利用Cookies维持登录状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import requests
# 利用Cookies维持知乎登录状态
url = 'https://www.zhihu.com/'
headers = {
'Cookies': '_zap=c74ffe60-fc10-4d88-8507-8b2f094ffe47; \
z_c0="2|1:0|10:1524489650|4:z_c0|92:Mi4xQU5UbkFnQUFBQUFB\
QUtDRUdyNThEU1lBQUFCZ0FsVk5zaXZMV3dBR1VjamtZZ3NWWVZBbjZEUV\
JFbElrTGpoOGZn|9ccd196c7209f86d929e45a1390e95ba02dc65699bce56\
f85c4725dec94e1365"; d_c0="ABBh7ahaiA2PTpF7sbd2mFngNGhU8hYDlnk=|1525268870";\
_xsrf=783a0476-0ab1-43a0-8d65-c5762532455d; q_c1=14b00bbf304245c79d6eb10cdb7\
195f6|1530178859000|1524489635000; __utmc=518543923; __utmv=51854390.100--|2=re\
gistration_date=20160419=1^3=entry_date=20160419=1; tgw_l7_route=69f52e0ac392bb4\
3ffb22fc18a173ee6; __utma=51854390.1263074800.1531224527.1531276507.1531281798.3; \
__utmb=51854390.0.10.1531281798; __utmz=51854390.1531281798.3.3.utmcsr=zhihu.com|u\
tmccn=(referral)|utmcmd=referral|utmcct=/',
'Host': 'www.zhihu.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \
Chrome/67.0.3396.99 Safari/537.36'
}
r = requests.get(url, headers= headers)
print(r.text)
c. 会话维持(Session)
Session模拟在一个浏览器中打开同一个站点的不同页面,模拟登录成功后接下来的一些操作。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import requests
#Session 会话维持
url_set = 'http://httpbin.org/cookies/set/number/1234'
url_get = 'http://httpbin.org/cookies'
s = requests.Session()
# 请求此网站时,设置一个cookie,名字是number,值是1234
rs = s.get(url_set)
print(rs.text)
#请求此网址获取当前的Cookies
r = s.get(url_get)
print(r.text)
d. SSL证书验证
…
爬取猫眼电影TOP100
1 | """ |