1.获取一个网页HTML
内容
一个网页,实质上就是一段HTML代码,加 JS、CSS,如果把网页比作一个人,那么HTML便是他的骨架,JS便是他的肌肉,CSS便是它的衣服。所以最重要的部分是存在于HTML中的,下面我们就写个例子来获取一个网页下来。
# 引入 urllib request 模块
import urllib.request
# 直接请求网页
response = urllib.request.urlopen("http://www.baidu.com")
# 获取请求结果
print(response.read().decode('utf-8'))
请求结果部分如下图:
2.分析抓取网页的方法
response = urllib.request.urlopen("http://www.baidu.com")
首先我们调用的是urllib
库里面的urlopen
方法,传入一个URL
,这个网址是百度首页,协议是HTTP
协议,当然你也可以把HTTP换做FTP,FILE,HTTPS 等等,只是代表了一种访问控制协议
urlopen
一般接受三个参数,它的参数如下:
urlopen(url, data, timeout)
第一个参数
url
即为URL
,第二个参数data
是访问URL
时要传送的数据,第三个timeout
是设置超时时间第二三个参数是可以不传送的,
data
默认为空None
,timeout
默认为socket._GLOBAL_DEFAULT_TIMEOUT
第一个参数
URL
是必须要传送的
在这个例子里面我们传送了百度的URL
,执行urlopen
方法之后,返回一个response
对象,返回信息便保存在这里面
response
对象有一个read()
方法,可以返回获取到的网页内容
response.read()
如果不加read()
直接打印, 是一个对象
<http.client.HTTPResponse object at 0x103038f98>
3.使用 Request
urllib.request.Request(_url, data=None, headers={}, method=None)
使用 request()
来包装请求,再通过urlopen()
获取页面
import urllib.request
# 请求 url
url = r'http://www.lagou.com/zhaopin/Python/?labelWords=label'
# 设置请求头,模拟浏览器访问
headers = {
'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)'
r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
'Referer': r'http://www.lagou.com/zhaopin/Python/?labelWords=label',
'Connection': 'keep-alive'
}
# 创建 request
req = request.Request(url, headers=headers)
# 打开 request
response = request.urlopen(req)
# 获取请求结果
page = response.read().decode('utf-8')
print(page)
参数解析:
User-Agent
:这个头部可以携带如下几条信息:浏览器名和版本号、操作系统名和版本号、默认语言。模拟浏览器请求Referer
:可以用来防止盗链,有一些网站图片显示来源http://***.com
,就是检查Referer
来鉴定的Connection
:表示连接状态,记录Session
的状态
4.GET 和 POST 数据传送
数据传送分为GET
和POST
两种方式
urlopen()
的data
参数默认为None
,即GET
请求;当data
参数不为空的时候,urlopen()
提交方式为 POST
GET方式:
至于GET方式我们可以直接把参数写到网址上面,直接构建一个带参数的URL出来即可
import urllib.request
import urllib.parse
params = urllib.parse.urlencode({'foo': 'bar'})
f = urllib.request.urlopen("https://httpbin.org/get?%s" % params)
print(f.read().decode('utf-8'))
输出结果:
{
"args": {
"foo": "bar"
},
"headers": {
"Accept-Encoding": "identity",
"Connection": "close",
"Host": "httpbin.org",
"User-Agent": "Python-urllib/3.6"
},
"origin": "211.94.116.108",
"url": "https://httpbin.org/get?foo=bar"
}
POST方式:
通过给 Request
方法 的data
属性设置值,即是 POST
请求
from urllib import request, parse
url = r'https://httpbin.org/post' headers = {
'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
'Referer': r'https://httpbin.org',
'Connection': 'keep-alive' }
data = {
'foo': 'bar',
'baz': ['a', 1]
}
data = parse.urlencode(data).encode('utf-8')
req = request.Request(url, headers=headers,data=data)
page = request.urlopen(req).read()
page = page.decode('utf-8')
print(page)
请求结果:
{
"args": {},
"data": "",
"files": {},
"form": {
"baz": "['a', 1]",
"foo": "bar"
},
"headers": {
"Accept-Encoding": "identity",
"Connection": "close",
"Content-Length": "30",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"Referer": "https://httpbin.org",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3"
},
"json": null,
"origin": "211.94.116.108",
"url": "https://httpbin.org/post"
}
异常处理
网络请求,很多原因会导致出错,对于异常,需要我们捕捉异常原因
使用 Python 的 try: except:
获取异常
1.URLError
URLError可能产生的原因:
- 网络无连接,即本机无法上网
- 连接不到特定的服务器
- 服务器不存在
代码示例:
import urllib.request
request = urllib.request.Request("http://www.baidu.com")
try:
response = urllib.request.urlopen(request)
except urllib.URLError as e:
print(e)
2.HTTPError
HTTPError是URLError的子类,在你利用urlopen方法发出一个请求时,服务器上都会对应一个应答对象response,其中它包含一个数字”状态码”
常见状态码
状态码 | 解释 |
---|---|
200 | 请求成功 |
400 | 非法请求 |
401 | 未授权 |
403 | 禁止 |
404 | 没有找到 |
500 | 服务器内部错误 |
501 | 服务器无法识别 |
… | … |
HTTPError
实例产生后会有一个code
属性,这就是是服务器发送的相关错误号
try:
response = urllib.request.urlopen(request)
except urllib.URLError as e:
print(e.code)
else:
print("OK")
使用代理 (Proxy)
当需要抓取的网站设置了访问限制,这时就需要用到代理来抓取数据
设置一些代理服务器来帮助你做工作,每隔一段时间换一个代理
urllib.request.ProxyHandler(proxies=None)
from urllib import request, parse
url = r'https://httpbin.org/post'
data = {
'foo': 'bar'
}
proxy = request.ProxyHandler({'http': '118.193.107.80:80'}) # 设置proxy
opener = request.build_opener(proxy) # 挂载opener
request.install_opener(opener) # 安装opener
data = parse.urlencode(data).encode('utf-8')
page = opener.open(url, data).read()
page = page.decode('utf-8')
print(page)