python爬虫综合概述(更新中...)

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库

 

上一篇:python-爬虫基础-lxml.etree(3)-Elementtree类


下一篇:python – xml.etree.ElementTree与lxml.etree:不同的内部节点表示?