今天我们来说说python爬虫的第一步!爬,爬这一步分为网站爬取和APP爬取,而网站爬取里面按照渲染方式,有分为服务器端渲染和客户端渲染,这么说是不是有点蒙,没关系你只需要知道今天说的是爬虫的一个必会的基础库,后续关于关于分类我会上一张图,你一看就懂了
基础库
服务器端渲染的基础请求库,分为这么几个
- urllib(原生底层库)
- urllib3(urlib的改良版)
- httplib2(基础请求库)
- pycurl(libcurl的python实现)
- httper(支持HTTP2新特性的库)
今天我们来说说第一个库,urllib
那么好,我们来提两个问题
1.urllib是什么?
2.urllib怎么用?
1.urllib是什么?
urllib是python内置的HTTP请求库
里面包括以下模块
urllib.request 请求模块
urllib.error 异常处理模块
urllib.parse url解析模块
urllib.robotparser robots.txt解析模块(用的太少了,本篇就不说的,附上urllib.robotparser官方文档,有需要的可以去看一下)
接下来来说一说这些模块的使用问题,也就是包含的模块怎么用!
一、urllib.request
- 请求模块,通俗点说就是用于获取网页的响应内容,也是爬虫的第一步!
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,cadefault=False,context=None)
这里面有三个常用的参数分别是
url:为请求网址
data:请求时需要发送的参数
timeout:超时设置,在该时间范围内返回请求内容就不会报错
eg:
from urllib import request
# 请求获取网页返回内容
response = request.urlopen('https://www.baidu.com/')
# 获取网页返回内容
print(response.read().decode('utf-8'))
# 获取状态码
print(response.status)
# 获取请求头
print(response.getheaders())
请求状态码:如果请求状态码为200,则正常访问
请求头:某些网站具有反爬功能,这时候我们就需要设置请求头进行伪装(以后我们会详细说)
eg:
# 请求头
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36'}
requests = request.Request('https://book.douban.com/', headers=headers) # 设置请求头
# 进行请求,把Request对象传入urlopen参数中
response = request.urlopen(requests)
- 通常我们请求网站时候使用的是GET方法,但是还有一种网站,需要登录以后才能看到登录后的信息,这时候我们需要使用POST方法,把需要进行登录提交的信息提交给服务器,服务器会响应我们的请求,返回登录后的界面
from urllib import request, parse
# 使用post方法来进行模拟登陆豆瓣
data = {'source': 'None',
'redir': 'https://www.douban.com/',
'form_email': 'user',
'form_password': 'passwd',
'remember': 'on',
'login': '登录'}
# 将data的字典类型转换为get请求方式
data = bytes(parse.urlencode(data), encoding='utf-8')
requests = request.Request('https://accounts.douban.com/login', headers=headers, data=data, method='POST')
response = request.urlopen(requests)
print(response.read().decode('utf-8'))
- 登录需要提交的信息设置在data里
- 类型是字典类型
- 请求方法设置为POST
上面我们提到了两种方法,这两种是HTTP常用的方法,有相似的地方就有比较,那么我们来说说这两种方法的比较
- GET -- 从指定的资源请求数据。
- POST -- 向指定的资源提交要被处理的数据
比较:
在登陆了之后我们,就需要获取一个非常重要的东西----Coookie,如果获取了cookie就可以保存我们的登陆信息,但是urlib获取cookie比较繁琐
from http import cookiejar
# 获取cookie
cookie = cookiejar.CookieJar()
# 获取助手把cookie传进去
handler = request.HTTPCookieProcessor(cookie)
# 获取opener进行请求网站
opener = request.build_opener(handler)
# 请求网页
response = opener.open('https://book.douban.com/')
# 将cookie保存在文件中
filename = 'cookie.txt'#cookie的文件名
cookie = cookiejar.MozillaCookieJar(filename) # 表示使用Mozilla的cookie方式存储和读取
handler = request.HTTPCookieProcessor(cookie)
opener = request.build_opener(handler)
opener.open('https://book.douban.com/')
# 保存文件
cookie.save(ignore_discard=True, ignore_expires=True)
还有一种保存方法,不过也是同样的繁琐
cookie = cookiejar.LWPCookieJar(filename) # 表示 Set-Cookie3 文件格式存储和读取
handler = request.HTTPCookieProcessor(cookie)
opener = request.build_opener(handler)
opener.open('https://book.douban.com/')
# 保存文件
cookie.save(ignore_discard=True, ignore_expires=True)
虽然写法不一样,但是保存的内容是一样的
保存了当然就是需要时候使用,那么cookie文件的使用
from http import cookiejar
# 从cookie文件加载到网页上实现记住登陆
cookie = cookiejar.LWPCookieJar()
# 加载文件
cookie.load(filename, ignore_discard=True, ignore_expires=True)
handler = request.HTTPCookieProcessor(cookie)
opener = request.build_opener(handler)
opener.open('https://book.douban.com/')
处理使用登陆的方式,网站还有一种来检测爬虫的方法,就是封IP,那么服务器凭什么认定,你是爬虫呢?就是检测该IP单位时间内访问的次数,如果超过了一个阈值,那么就认为你是爬虫,就会对你封IP,所以我们有时候需要代理来防止IP被封(关于代理我们以后会详细说)
现在来说一下urlib库使用代理的方法:
import urllib.request
proxy_handler = urllib.request.ProxyHandler({
'http': 'http://127.0.0.1:9743',
'https': 'https://127.0.0.1:9743'
})
opener = urllib.request.build_opener(proxy_handler)
response = opener.open('http://book.douban.com/',timeout=1)
print(response.read())
二、urllib.error
该模块是异常处理模块,用于处理异常操作,是为了当程序出现异常时候我们希望的是程序出现提示,而不是程序停止
eg
from urllib import request, error
try:
proxy_handler = urllib.request.ProxyHandler({
'http': 'http://127.0.0.1:9743',
'https': 'https://127.0.0.1:9743'
})
opener = urllib.request.build_opener(proxy_handler)
response=opener.open('https://movie.douban.com/', timeout=1)
except error.HTTPError as e:
print(e.reason(), e.code(), e.headers())
except error.URLError as e:
print(e.reason)
捕获异常我们用try.....except,如果程序出现异常,会提示HTTPError /URLError ,从而给出提示,而不是程序停止
三、urllib.parse
urlib解析模块,用于解析URL
urllib.parse.urlparse(url, scheme=”, allow_fragments=True)
eg:
from urllib import request, parse
# 解析url
print(parse.urlparse('https://book.douban.com/'))
print(parse.urlparse('https://book.douban.com/', scheme='http'))
print(parse.urlparse('book.douban.com/', scheme='http'))
# 下面是结果
ParseResult(scheme='https', netloc='book.douban.com', path='/', params='', query='', fragment='')
ParseResult(scheme='https', netloc='book.douban.com', path='/', params='', query='', fragment='')
ParseResult(scheme='http', netloc='', path='book.douban.com/', params='', query='', fragment='')
scheme参数一般会忽略
URL的拼接
from urllib.parse import urlunparse
# 将列表元素拼接成url
data = ['http', 'www.baidu.com', 'index.html', 'user', 'a=6', 'comment']
print(urlunparse(data))
# 下面是结果
http://www.baidu.com/index.html;user?a=6#comment
- urllib.parse.urljoin():这个是将第二个参数的url缺少的部分用第一个参数的url补齐
from urllib.parse import urljoin
print(urljoin('http://www.baidu.com', 'FAQ.html'))
print(urljoin('http://www.baidu.com', 'https://cuiqingcai.com/FAQ.html'))
结果
http://www.baidu.com/FAQ.html
https://cuiqingcai.com/FAQ.html
- urllib.parse.urlencode():这个方法是将字典类型的参数转为请求为get方式的字符串(显示的提交数据)
from urllib.parse import urlencode
params = {
'name': 'germey',
'age': 22
}
base_url = 'http://www.baidu.com?'
url = base_url + urlencode(params)
print(url)
结果
http://www.baidu.com?name=germey&age=22
四、后记
个人感觉urlib系列的库,不如requests库用着舒服,有些东西写法很繁琐,但是毕竟是底层库,我们还是学习一下,最后惯例,附上url官方文档最新的,希望对你有所帮助!晚安~