基本库的使用

urllib

urlopen

1
urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,*, cafile=None, capath=None, cadefault=False, context=None)

data

1
2
3
4
5
6
7
8
9
10
11
12
13
print(urllib.parse.urlencode({"my_key": "my_value"}))
# 将键值对编码为可用url传递的格式
# my_key=my_value

print(urllib.parse.urlencode({"my_key": {"key_2":"value_2"}}))
# 复杂格式的键值对
# my_key=%7B%27key_2%27%3A+%27value_2%27%7D

data = bytes(urllib.parse.urlencode({"my_key": {"key_2":"value_2"}}), encoding="utf8")
# data数据使用前要转化为字节流类型

response = urllib.request.urlopen('http://httpbin.org/post',data=data)
print(response.read().decode('utf8'))

timeout

timeout 参数用于设置超时时间,单位为秒,意思就是如果请求超过了设置的这个时间, 还没有得到响应 就会抛出异常。如果不指定该参数,就会使用全局默认时间它支持 HTTP、HTTPS、FTP请求。

其他参数

除了 data 参数和 timeout 参数外,还有 context 参数,它必须是 ssl.SSLContext 类型,用来指定SSL。此外, cafile和capath 这两个参数分别指定 CA 证书和它的路径,这个在请求 HTTPS 链接时有用。
cadefault 参数现在已经弃用了,其默认值为 False。

request

1
2
3
request = urllib.request.Request('http://httpbin.org/get')
response = urllib.request.urlopen(request)
print(response.read().decode('utf8'))

类request(url, data=None, headers={},origin_req_host=None, unverifiable=False,method=None)
data:必须为字节流类型
headers:请求头,字典。也可用实例的add_header()方法添加
origin_req_host:请求方的host名称或IP地址
unverifiable:表示这个请求是否是无法验证的,默认是 False ,意思就是说用户没有足够权限来选择接收这个请求的结果 例如,我们请求 HTML 文档中的图片,但是我们没有向自动抓取图像的权限,这时 unverifiable 的值就是 True

Handler

  • 验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
from urllib.error import URLError

username = 'username'
password = 'password'
url = 'http://localhost:80/'
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)
  • 代理
1
2
3
4
5
6
7
8
9
10
11
12
13
from urllib.error import URLError
from urllib.request import ProxyHandler, build_opener

proxy_handler = ProxyHandler({
'http ': 'http://127.0.0.1:9743 ',
'https': 'https://127.0.0.1:9743 '
})
opener = build_opener(proxy_handler)
try:
response = opener.open('https://www.baidu.com')
print(response.read().decode('utf-8'))
except URLError as e:
print(e.reason)
  • Cookies

将网站的 Cookies 获取下来

1
2
3
4
5
6
7
8
import http.cookiejar, urllib.request

cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open(' http://www.baidu.com')
for item in cookie:
print(item.name + '=' + item.value)

Cookies存文件

1
2
3
4
5
6
7
8
import http.cookiejar, urllib.request

filename = 'cookies. txt'
cookie = http.cookiejar.MozillaCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard=True, ignore_expires=True)

读Cookies

1
2
3
4
5
6
cookie = http.cookiejar.LWPCookieJar()
cookie.load('cookies.txt', ignore_discard=True, ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))

异常处理

URLError

URLError 类来自 urllib 库的 error 模块,它继承自 OSError 类,是 error 异常模块的基类,由 request模块生的异常都可以通过捕获这个类来处理
它具有一个属性 reason ,即返回错误的原因。

HTTPError

它是 URLError 的子类,专门用来处理 HTTP 请求错误,比如认证请求失败等 它有如下三个属性
code、reason、headers

因为 URLError是HTTPError 的父类,所以可以先选择捕获子类的错误,再去捕获父类的错误,所以上述代码更好的写法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import socket
from urllib import request, error

try:
response = request.urlopen('https://cuiqingcai.com/index.htm',timeout=0.1)
except error.HTTPError as e:
print(e.reason, e.code, e.headers)
except error.URLError as e:
# 有时候, reason 属性返回的不一定是字符串,也可能是一个对象
if isinstance(e.reason, socket.timeout):
print(' TIME OUT')
else:
print(e.reason)
else:
print('Request Successfully')

解析链接

urlparse

该方法可以实现 URL 的识别和分段
scheme://netloc/path;params?query#fragment

urlunparse

有了 urlparse (), 地就有了它的对立方法 urlunparse () 它接受的参数是一个可迭代对象,但是它的长度必须是6

1
2
3
4
from urllib.parse import urlunparse

data = ['http', 'www.baidu.com', 'index.html', 'user', 'a=6', 'comment' ]
print(urlunparse(data))

其他

1
2
3
4
5
6
7
8
urlsplit
urlunsplit
urljoin
urlencode:参数序列化适应GET请求
parse_qs:反序列化为字典
parse_qsl:反序列化为元组组成的列表
quto:将内容转化为 URL 编码的格式
unquto

Robots协议

1
2
3
User-agent: *  (允许的爬虫名称,至少得有一个)
Disallow: (/表根目录,禁止所有访问)
Allow: /public/

robotparser

1
2
3
4
5
6
7
8
from urllib.robotparser import RobotFileParser

rp = RobotFileParser('http://example.webscraping.com/robots.txt')
rp.read()
print(rp.can_fetch('BadCrawler', 'http://example.webscraping.com'))
# False
print(rp.can_fetch('GoodCrawler', 'http://example.webscraping.com'))
# True

requests

get

获取图片、音频、视频
二进制存文件即可

1
2
3
4
5
import requests

r = requests.get('https://github.com/favicon.ico')
with open('cc.ico','wb') as f:
f.write(r.content)

高级用法

文件上传

1
2
3
4
5
import requests

files = {'file': open('favicon.ico', 'rb ')}
r = requests.post('http://httpbin.org/post', files=files)
print(r.text)

Cookies

可直接添加在headers里面
或者

1
2
3
jar = requests.cookies.RequestsCookieJar()
jar.set(key, value)
r = requests.get(url,cookies=jar,headers =headers)

会话维持

等同于一个浏览器多个标签页
即同一个Cookies

1
2
3
4
5
6
import requests

s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789')
r = s.get('http://httpbin.org/cookies')
print(r.text)

SSL 证书验证

当遇到证书错误时修改verify参数忽略,但仍会获得一个警告
response = requests.get('https://www.12306.cn',verify=False)
可以忽略警告

1
2
from requests.packages import urllib3 
urllib3.disable_warnings()

或者通过捕获警告到日志的方式忽略警告

1
2
import logging 
logging.captureWarnings(True)

或使用本地证书(略)

代理设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests
import random

proxy = [
{
'http': 'http://61.135.217.7:80',
'https': 'http://61.135.217.7:80',
},
{
'http': 'http://118.114.77.47:8080',
'https': 'http://118.114.77.47:8080',
},
{
'http': 'http://112.114.31.177:808',
'https': 'http://112.114.31.177:808',
}
]
url = '爬取链接地址'
response = requests.get(url, proxies=random.choice(proxy))

若代理需要使用 HTTP Basic Auth ,可以使用类似 http://user:password@host:port 这样的语法来置代理
SOCKS 协议代理(略)

超时设置

response = requests.get(url, timeout=(5,13))
元组代表“连接”与“读取”超时
留空或None代表永久等待

身份认证

auth=HTTPBasicAuth (’username ',’password')
或者auth =(’ username ,’ password')
或者 OAuth 认证pip3 install requests oauthlib

Prepared Request

各个参数都可以通过一个Request象来表示