1.urllib库
1、urllib库主要包含4个模块:
①request : 它是最基本的HTTP 请求模块,可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样,只需要给库方法传入URL 以及额外的参数,就可以模拟实现这个过程了。
②error : 异常处理模块,如果出现请求错误, 我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止。
③parse : 一个工具模块,提供了许多URL 处理方法,比如拆分、解析、合并等。
④robotparser :主要是用来识别网站的robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬,它其实用得比较少
request 模块:
1、urlopen()函数
HTTPResposne urllib.request.urlopen(url, data=None,[timeout,]*, cafile=None, capath=None, cadefault=False, context=None)
#data参数:传递post请求的参数,如果它是字节流编码格式的内容,即bytes 类型,则需要通过bytes()方法转化
#timeout参数:以s计,超时后抛出URLError:timeout异常
#cafile参数:
#capath参数:
#cadefault参数:弃用,默认false
#context参数:必须是ssl.SSLContext 类型,用来指定SSL设置
2、Request类
class urllib.request.Request (url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
#url, data(post请求的参数数据)与urlopen相同
#headers:请求头,字典结构。可以在构造请求时通过headers 参数直接构造,也可以通过调用请求实例的add_header()方法添加
#origin_req_host:请求方的主机ip
#unverifiable:是否有请求权限,没有即为true
#method:get,post,put等
Request类可以传入urllib函数:
request = urllib.request.Request ('https://python.org')
response = urllib.request.urlopen(request)
Request类其他参数设置:
from urllib import request, parse
url = 'http://...'
headers = {
'User-Agent': 'Chrome/3.0 (compatible; MSIE 4.5; Window 10)',
'Host':'...'
}
dict = {
'name':'value'
}
data = bytes(parse.urlencode(dict), encoding='utf8')
#使用4个参数构造请求体
req = request.Request(url = url, data = data, headers = heardes, method = 'post')
res = request.urlopen(req)
print(response.read().decode('utf-8'))
3、高级功能——使用 Handler
这部分先不总结,因为用的更多的是requests库,使用高级功能更简单。
error 模块:
1、URLError 类:
URLError类来自urllib库的error模块,继承自OSError类,是error异常模块的基类。有一个属性reason,返回错误的原因。
2、HTTPError 类:
HTTPError继承自URLError。专门处理HTTP请求错误。有三个属性:code,reason,headers
URLError是HTTPError的父类,所以可以先捕获子类错误,在捕获父类错误:
from urllib import request, error
try:
response = request.urlopen('https://www.baidu.com')
#先捕获子类HTTPError
except error.HTTPError as e :
print(e.reason, e.code, e.headers, sep = '\n')
#再捕获父类URLError
except error.URLError as e:
print(e.reason)
else:
pass #successful
parse 模块:
parse模块定义了一堆处理URL的函数。
首先,扒扒URL是啥样的:
格式:scheme://netloc/path;params?query#fragment
示例:https://www.baidu.com/index.html;user?id=3#comment
scheme代表协议,netloc代表域名,path代表路由,params代表参数,query是查询条件,fragment是锚点
1、urlparse()
该方法可以实现URL的识别和分段
urllib.parse.ParseResult urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
#scheme:默认协议,如果链接没有带协议信息,则会加上这个作为默认协议
#allow_fragments:是否忽略fragment
#返回结果是ParseResult类,结构如下:
<class 'urllib.parse.ParseResult'>
ParseResult(scheme='http', netloc= www.baidu.com', path='/index.html',params='user', query='id=3',fragment='comment')
#示例:
result= urlparse('http://www.baidu.com/index.html;user?id=3#comment')
#结果如下:
ParseResult(scheme ='http',netloc =’www.baidu.com', path='/index.html ’,params ='user', query ='id=3',fragment= 'comment')
2、urlunparse()
data =['http', 'www.baidu.com ', 'index.html', 'user' ,'a=6', 'comment']
print(urlunparse(data))
#运行结果如下:
http://www.baidu.com/index.html;user?a=6#comment
3、urlsplit() 与urlpares()的区别是不再解析params部分,返回5个结果,params并入path部分
#示例:
result= urlsplit('http://www.baidu.com/index.html;user?id=3#comment')
#结果如下:
ParseResult(scheme ='http',netloc =’www.baidu.com', path='/index.html;user’, query ='id=3',fragment= 'comment')
4、urlunsplit() urlsplit()的逆过程
5、urljoin(base_url, new_url)
解析base_url的scheme、netloc、path这三个内容,对new_url缺失的部分进行补充。 即方便实现https://www.baidu.com/index.html(来源于base_url) + 其他(来源于new_url)。
6、urlencode() 序列化。
便于将字典结构序列化成参数。示例:
from urllib.parse import urlencode
params = {
'name' : 'value',
'age':22
}
base_url = 'https://www.baidu.com?'
url = base_url + urlencode(params)
print(url)
#输出为
https://www.baidu.com?name=value&age=22
7、parse_qs() 反序列化。query部分:‘name=value&age=22’ 转换成字典 { 'name' : 'value' , 'age':22}。
8、parse_qsl() 反序列化。query部分:‘name=value&age=22’ 转换成元组组成的列表 [('name' ,'value') , ('age',22)]。
9、quote()
将内容转换成URL编码,URL有中文时,可能出现乱码,使用 quote() 函数将中文字符转换成URL编码。示例:
from urllib.parse import quote
keyword ='壁纸’
url ='https://www.baidu.com/s?wd=’+ quote(keyword)
print(url)
#输出
https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8
10、unquote()
from urllib.parse import unquote
url =unquote('https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8')
print(url)
#输出
https://www.baidu.com/s?wd=壁纸
robotparser 模块
首先,扒扒Robots协议。实际上就是放在网站根目录下的robots.txt文件,可以通过/robots.txt访问到。比如可以看到网易的robots.txt:
User-agent: Sosospider //soso爬虫
Disallow: / //啥都不让爬
好像没什么作用,给个例子:
from urllib.robotparser import RobotFileParser
fp = RobotFileParser('http://quotes.money.163.com')
fp.read()
print(fp.can_fetch('*', 'http://quotes.money.163.com/trade'))
#输出 true, 和 robots文件是冲突的。。。
2、requests库
1、get请求
requests.models.Response requests.get(url, params, auth, headers, cookies, allow_redirects, stream=false, timeout=None,)
#params:传入字典作为params
#auth:登录信息,使用元组即可,('username', 'password')
#hearders:传入请求头,有些网站没有浏览器标示不让爬,请求头也可以写入cookies
#cookies:传入cookies,可在请求头中完成
#allow_redirects:是否处理重定向。除了HEAD请求,其他请求默认处理重定向
#stream:是否获取来自服务器的原始套接字响应
#timeout:超时
返回类型:requests.models.Response
成员:status_code,text,content,cookies,json(),url,history(请求历史)
2、文件上传和下载
import requests
#下载示例:
response = requests.get('https://2.python-requests.org//zh_CN/latest/_static/requests-sidebar.png')
with open(D://pic.png) as f:
f.write(response.content)
#上传示例:
url = 'http://httpbin.org/post'
files = {'file': open('report.png', 'rb')} #更多上传选项参考手册
r = requests.post(url, files=files) #注意,post才能上传文件
r.text
3、post请求:get请求中params改datas,可以用参数files上传文件
4、会话维持:示例:
import requests
s = requests.Session() #后面的行为将在同一session下执行
s.get(...)
5、SSL与Proxy ——再单独写
6、身份认证:Requests 在 requests.auth
中提供了两种常见的的身份验证方案: HTTPBasicAuth
和 HTTPDigestAuth
。使用请求中的auth参数接收两种方案的数据类型,也可以接收俩个字符串组成的的元组。
7、PreparedRequest
使用urllib中的urlopen()函数可以传入Request类作为参数,requests也可以使用这个类。
有时在发送请求之前,需要对 body 或者 header (或者别的什么东西)做一些额外处理。
from requests import Request, Session
s = Session()
req = Request('GET', url,
data=data,
headers=header
)
prepped = req.prepare()
# do something with prepped.body
# do something with prepped.headers
resp = s.send(prepped,
stream=stream,
verify=verify,
proxies=proxies,
cert=cert,
timeout=timeout
)
print(resp.status_code)
8、抛出错误:RequestException
3.正则表达式
主要复习python的re库,正则部分,单独写一篇。
#### re库的3大匹配函数:
# 1、_sre.SRE_Match match(patten, content, modifier) #只能从头匹配
# 返回结果:_sre.SRE_Match,通过group()(或group(0))查看匹配的字符串, group(num)查看每个分组
# patten:正则表达式,①以正则表达式字符串传入,②以正则表达式对象_sre.SRE_Pattern传入
# content:待匹配的字符串
# modifier:修饰符,如re.S表示.号可以匹配换行符等等
# 2、_sre.SRE_Match search(patten, content, modifier) #任意匹配
# 3、list findall(patten, content, modifier)
# 返回一个元组列表,元组内为每个group的匹配值:[(group(1),group(2),...),(group(1),group(2),...)...]
#### compile()函数
# _sre.SRE_Pattern compile(patten)
# 返回值:正则表达式对象_sre.SRE_Pattern
# patten:正则表达式字符串
#### sub()函数
# sub(patten, '',content) 把字符串匹配的部分砍掉,中间一般留空参''
4、lxml库 使用XPath
XPath常用规则 | |
nodename | 选取此节点的所有子节点 |
/ | 从当前节点选取直接子节点 |
// | 从当前节点选取子孙节点 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
etree模块:
1、HTML()函数 返回 lxml.etree._Element类
HTML()函数用于修正HTML文档,比如补齐缺漏,修正不规范等。
# lxml.etree._Element etree.HTML(text)
# 返回类型:lxml.etree._Element
# text:参数,html文本
# 示例:
response = requests.get('https://www.baidu.com')
text = response.text
html = etree.HTML(text)
result = etree.tostring(html)
print(result.decode('utf-8'))
2、parse()函数 返回 lxml.etree._Element类
parse()函数用于解析本地的html文件。
# lxml.etree._Element etree.parse(path, fun)
# 返回类型:lxml.etree._Element
# path:参数,html文件路径
# fun:解析函数,HTML文件用 etree.HTMLParser()
# 示例:
html = etree.parse('D://Users//Tommy//Desktop//html.html', etree.HTMLParser())
result = etree.tostring(html)
print(result.decode('utf-8'))
3、tostring()函数 lxml.etree._Element 转 string
4、xpath()函数
类 lxml.etree._Element 的成员函数 xpath(),执行XPath规则。示例:
import requests
from lxml import etree
response = requests.get('https://www.baidu.com')
text = response.content.decode('utf-8')
html = etree.HTML(text, etree.HTMLParser())
result = html.xpath('//div//text()') #显示div子孙节点内容
result = html.xpath('//li[@class="item-0"]/text()') #筛选出li节点属性class="item-0"的节点,显示子节点内容
result = html.xpath('//li[@class="li"]/a/text()') #筛选出li节点属性class="li"的节点,显示a子节点的内容
result = html.xpath('//li[contains(@class, "li")]/a/text()') #class属性有多个值时(li是其中一个属性)
result = html.xpath('//li[contains(@class, "li") and @name="item"]/a/text()') #多属性匹配
result = html.xpath ('//li/a/@href') #属性获取
result = html.xpath('//div[2]/a/text()') #显示第2个div节点的a子节点的内容
print(result)
5、Beatiful Soup库