0. 为什么学习爬虫
上班之后,论文的学习逐渐落下了,最近工作步入了正轨(刚加完一个月的班:)),加上之前在研究生期间主做GAN,人工智能的其他领域研究比较少,所以想在空闲时间读读论文,复现复现论文,计划是都学一下,包括但不限于目标检测、图像分割、nlp、知识图谱。然后,在做准备工作时,突然发现可能需要学点简单的爬虫知识来构建数据集。这几天简单的学习了一下,也实战了一下,过来做一下笔记,写得比较简单,本人小白,有错误也请指正。
1. 读取网页的最基本操作
import urllib.request
request = urllib.request.Request(url(str类型))
response = urllib.request.urlopen(request)
response.read().decode("utf-8")
其中urlopen中包含了三个参数,分别是url、data、timeout代表了网址、网址参数、超时时间。data如果不传参则为get方法,传参则为post方法。
import urllib.request
import urllib.parse
import urllib.error
request = urllib.request.Request(url)
data = bytes(urllib.parse.urlencode({"key":"value"}), "utf-8")
response = urllib.request.urlopen(request, data)
try:
request = urllib.request.Request(url)
response = urllib.request.urlopen(request, timeout=1) #1秒后没连接上报错
except urllib.error.URLError as e:
print(e.reason)
print("Time out!")
response实例中提供了status属性和getheaders()分别表示响应的状态和头部信息
2. 关于Request的附加信息
在实际发送请求操作中,往往需要额外的信息
-
头部信息的添加
有两种添加方法,第一种:import urllib.request headers = { 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)', 'Host': 'httpbin.org' } request = urllib.request.Request(url, headers=headers, method='POST') response = urllib.request.urlopen(request)
第二种:
from urllib import request req = request.Request(url=url, data=data, method='POST') req.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)') response = request.urlopen(req)
-
设置代理IP
也有两种设置方法,局部代理:import urllib.request proxy_handler = urllib.request.ProxyHandler({ "http" : "27.206.177.148:80" }) nullproxy_handler = urllib.request.ProxyHandler({}) proxySwitch = True if proxySwitch: opener = urllib.request.build_opener(proxy_handler) #设置代理 else: opener = urllib.request.build_opener(nullproxy_handler) #关闭代理 request = urllib.request.Request("http://www.baidu.com") response = opener.open(request) #只能用open发起请求
全局代理:
urllib.request.install_opener(opener) response = urllib.request.urlopen(request)
-
携带Cookie信息,Cookie主要用于登录,第一次登录时Cookie为空,登录后响应中包含Cookie,后面发起请求时带上Cookie,无需再次登录。
import http.cookiejar cookie = http.cookiejar.CookieJar() #建一个cookie对象,目前是空的 handler = urllib.request.HTTPCookieProcessor(cookie) #建一个处理器处理cookie opener = urllib.request.build_opener(handler) response = opener.open('http://www.baidu.com') #请求结束会返回cookie,直接存入cookie对象中 for item in cookie: print(item.name+"="+item.value)
Cookie的序列化(主要使用MozillaCookieJar):
cookie = http.cookiejar.MozillaCookieJar(cookie_filename) handler = urllib.request.HTTPCookieProcessor(cookie) opener = urllib.request.build_opener(handler) resp = opener.open(url) cookieStr = '' for item in cookie: cookieStr = cookieStr + item.name + '=' + item.value + ';' print(cookieStr) cookie.save()
Cookie的反序列化:
cookie = cookiejar.MozillaCookieJar() cookie.load(cookie_filename) handler = urllib.request.HTTPCookieProcessor(cookie) opener = urllib.request.build_opener(handler) resp = opener.open(req) cookieStr = '' for item in cookie: cookieStr = cookieStr + item.name + '=' + item.value + ';' print(cookieStr)
-
有多个handler时,opener对象可以使用add_handle(handler)
3.异常处理
之前有稍微提到一下超时异常的处理,在urllib中只有两种异常,URLError和HTTPError,其中HTTPError是URLError的子类。
在URLError中,只有一个属性reason,HTTPError中有三个属性:code、reason、headers。
try:
response = urllib.request.urlopen("http://1234asdfadf56.com")
except urllib.error.HTTPError as e:
print(e.reason)
print(e.code)
print(e.headers)
except urllib.error.URLError as e:
print(e.reason)
也可根据reason的类型来进一步判断,比如获取目标地址错误:
try:
response = urllib.request.urlopen("http://eadfadfasdf.com", timeout=1)
except urllib.error.URLError as e:
# print(type(e.reason))
if isinstance(e.reason, socket.gaierror):
print("获取目标地址失败!")
4.URL解析和参数拼接
-
URL解析
from urllib.parse import urlparse print(urlparse("https://www.baidu.com/s?ie=utf-8&wd=python")) #输出:ParseResult(scheme='https', netloc='www.baidu.com', path='/s', params='', query='ie=utf-8&wd=python', fragment='')
其中 scheme 是协议 netloc 是域名服务器 path 相对路径 params是参数,query是查询的条件
-
URL参数拼接
from urllib.parse import urlencode params = { "ie":"utf-8", "ws":"python", } base_url = "https://www.baidu.com/s?" url = base_url+urlencode(params) print(url) #输出结果:https://www.baidu.com/s?ie=utf-8&ws=python