Python 第三方模块 爬虫 Requests模块,Beautifulsoup模块

22 篇文章 0 订阅
7 篇文章 0 订阅

一.什么是爬虫(Web Crawler)
1.概念:

爬虫是1段自动抓取互联网信息的程序,用于从互联网上抓取有价值的信息
分为定向爬虫(只抓取目标网站上的信息)和非定向爬虫(没有针对性,所有链接都爬取)2

2.基本原理:

①向指定地址发送请求,然后下载该页面
②用正则表达式进行匹配,筛选出需要的内容

3.实例:

import requests,bs4

response=requests.get("https://www.autohome.com.cn/all/#pvareaid=3311230")
response.encoding=response.apparent_encoding
soup=bs4.BeautifulSoup(response.text,features="html.parser")
target=soup.find(id="auto-channel-lazyload-article")
li_list=target.find_all("li")
for obj in li_list:
    i=obj.find("a")
    if i:
        print(i.find("h3").text)

二.Requests模块

官方文档:http://cn.python-requests.org/zh_CN/latest/user/quickstart.html#id4

1.介绍:

Python内置了urllib/urllib2/httplib等模块供Http请求使用.但是,这些模块的API难以使用,需要大量的工作来完成1个简单的任务

Requests是使用Apache2 Licensed的基于Python开发的HTTP库,其在Python内置模块的基础上进行了高度封装,使得进行网络请求的操作
得到了极大简化.使用Requests可以轻易完成浏览器可有的任何操作

2.基本方法:

更多实例参见:https://www.cnblogs.com/wupeiqi/articles/6283017.html
关于User-Agent参数参见:https://www.jianshu.com/p/c5cf6a1967d1
关于参数json和data参见:https://blog.csdn.net/Mr_know/article/details/107002686

#以下发送各种请求的方法均是在调用此方法:
<re>=requests.request("<method>","<url>"[,params=None,data=None,json=None,headers=None,cookies=None,files=None,auth=None,timeout=None,allow_redirects=True,proxies=None,verify=True,stream=False,cert=None])
    method:请求方法;str,"get"/"post"
      #如requests.request("get","<url>")相当于requests.get("<url>")
    url:指定URL;str
      #也可以写成关键字参数url
    以下参数为 二.3 部分中**kwargs参数可能的取值:
      params指定在URL中传递的参数(即以GET形式提交的数据)
        #为dict/list/tuple/bytes(只能包含ASCII中的字符)/str(可以包含ASCII中没有的字符)
      data指定在请求体中传递的数据(即以POST形式提交的数据)
        #为dict/list/tuple/bytes/str/file;通常使用dict形式
        #在发送前都会被转换成str的形式再编码,不论传入什么形式
        #data中的键/值只能是str/num/list;如果是dict,则只发送键而不发送值
      json也指定在请求体中传递的数据,不过会自动转换为json的格式(即json.dumps())
        #Django通过请求头中的Content-Type来确定请求体中的数据格式(json或str),再进行相应的处理
        #json对应的请求头信息是{"Content-Type":"application/json"}
        #如果参数中的键/值是dict(即参数中嵌套了dict),只能使用json,不能用data
      headers指定请求头;dict
        ①Referer:访问的上1个网站
          #很多网站只有在该参数是其自身时才允许登录(见下图)
          #因为通过浏览器必须先访问1次才能进入登录界面
        ②User-Agent:通过什么工具进行的访问
      cookies指定要发送的cookies(放在请求头里)
        #为dict/CookieJar
      files:指定要上传的文件
        #为dict,格式为{"<name>":<file_obj>...}
        #也可以是其他格式,详情参见源码注释
      auth:指定要发送的用于HTTP Auth的用户名/密码
        #为tuple,格式为<func>("<username>","<pwd>")
        #func可为HTTPBasicAuth/HTTPCustomAuth/HTTPDigestAuth
        #也可以通过headers定制Authentication字段来实现
      timeout:超时时限(即等待Server响应的最大时长)
        #为float/tuple,后者的格式为(<connect_timeout>,<read_timeout>)
      allow_redirects:是否允许进行重定向跳转;bool
      proxies:指定代理的URL;dict
        #常用于绕开网站对IP的限制
      verify:bool(是否进行SSL/TLS验证)/str(指定CA bundle文件)
        #为False时即使使用HTTPS也不进行验证
      stream:是否采用"流"的形式接收返回的内容;bool
        #如果为True,则每次只下载一小部分;为False,则一次性下载全部
        #设为True可防止内存过小时无法同时加载全部内容
      cert:若为str,指定用于SSL/TLS验证的证书(.pem文件)
             #HTTPS协议即使用SSL进行验证
           若为tuple,同意指定上述证书,格式为("<f1>.crt","<f2>.key")
             #这只是2种不同的格式,功能是相同的
             #还有些证书是内置在计算机中的,不需要自己手动发送
      re:Server返回的requests.models.Response对象
        #这是1个字节对象

#实例1:
response=requests.request(
    "post",
    "http://dig.chouti.com/",
    params={"k1":"v1","k2":"v2"},
    #最后发送的URL相当于http://www.google.com?k1=v1&k2=v2
    data="user=john&pwd=123",
    #即使此处传入的是dict,也会先转换成如上的str形式并编码,然后再发送
    json={"user":"john","pwd":"123"},
    #会自动转换成json格式而不会转换成如上的str形式
    headers={
      "Referer":"http://dig.chouti.com/"
      #很多网站都被设置为只有本参数(即访问的上1个网站)是其自身的时候才允许登录
      "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
      #说明是通过Chrome浏览器进行的该访问
    },
    file={
        "f1":open("s1.py","wb"),
        #f1是自定义的key;在Server使用的文件名是s1.py
        "f2":("sc1.py",open("s2.py","wb"))
        #sc1.py是在Server使用的文件名
    },
    auth=HTTPBasicAuth("smith","123123"),
    #相当于在headers中增加"Authentication":_basic_auth_str("smith","123123")
    proxies={
        "http":"http://4.19.128.5:8099"
        #所有HTTP请求都通过该代理进行
    }
)

#实例2(关于stream参数):
from contextlib import closing
with closing(requests.get('http://httpbin.org/get', stream=True)) as r:
    for i in r.iter_content():#在此处理响应,每次循环只接收一小部分
        print(i)

在这里插入图片描述
3.发送请求:

<re>=requests.get("<url>",params=None[,**kwargs]):发送GET请求
  #参数说明:同requests.request()

#无参实例:
>>> re=requests.get("https://www.autohome.com.cn/beijing/")
>>> print(re)
<Response [200]>
>>> print(type(re))
<class 'requests.models.Response'>
>>> re.encoding=re.apparent_encoding
#.encoding指定使用的解码方式;.apparent_encoding表示原数据使用的编码方式
>>> print(re.text)#这里只截取了结果中间部位的一小部分
#.text表示对象中的文本内容
...
<div id="auto-header" class="topbar">
    <div id="auto-header-inner" class="topbar-inner">
        <!-- mini begin -->
        <div class="topbar-mini">
            <div class="mini-main">
...
>>> print(type(re.text))
<class 'str'>

#有参实例:
>>> import requests
>>> payload={'key1': 'value1', 'key2': 'value2'}
>>> re=requests.get("http://httpbin.org/get",params=payload)
>>> print(re)
<Response [200]>
>>> print(re.text)
{
  "args": {
    "key1": "value1",
    "key2": "value2"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.24.0",
    "X-Amzn-Trace-Id": "Root=1-5f202eb1-72b8d5fcb6f97326b8e295fc"
  },
  "origin": "111.192.245.200",
  "url": "http://httpbin.org/get?key1=value1&key2=value2"
}

>>> print(re.url)
http://httpbin.org/get?key1=value1&key2=value2

###############################################################################################################

<re>=requests.post("<url>",data=None,json=None[,**kwargs]):发送POST请求
  #参数说明:同requests.request();data和json应至少使用1个

#不指定请求头的实例:
>>> import requests
>>> payload={'key1': 'value1', 'key2': 'value2'}
>>> print(re.text)
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "key1": "value1",
    "key2": "value2"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Content-Length": "23",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.24.0",
    "X-Amzn-Trace-Id": "Root=1-5f2031ba-8d79bd8105cf3c5b5fd43a5d"
  },
  "json": null,
  "origin": "111.192.245.200",
  "url": "http://httpbin.org/post"
}

>>> print(re.content)
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "key1": "value1", \n    "key2": "value2"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "23", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.24.0", \n    "X-Amzn-Trace-Id": "Root=1-5f2031ba-8d79bd8105cf3c5b5fd43a5d"\n  }, \n  "json": null, \n  "origin": "111.192.245.200", \n  "url": "http://httpbin.org/post"\n}\n'

#指定请求头的实例:
>>> import requests,json
>>> url='http://httpbin.org/post'
>>> data={'some':'data'}
>>> headers={'content-type':'application/json'}
>>> re=requests.post(url,data=json.dumps(payload),headers=headers)
>>> print(re.text)
{
  "args": {},
  "data": "{\"key1\": \"value1\", \"key2\": \"value2\"}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Content-Length": "36",
    "Content-Type": "application/json",#手动指定的请求头信息
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.24.0",
    "X-Amzn-Trace-Id": "Root=1-5f203333-c3e163e8e9bfd0b8928f020a"
  },
  "json": {
    "key1": "value1",
    "key2": "value2"
  },
  "origin": "111.192.245.200",
  "url": "http://httpbin.org/post"
}

>>> print(re.cookies)
<RequestsCookieJar[]>

###############################################################################################################

requests.put("<url>",data=None[,**kwargs]):发送put请求
requests.head("<url>"[,**kwargs]):发送head请求
requests.delete("<url>"[,**kwargs]):发送delete请求
requests.patch("<url>",data=None[,**kwargs]):发送patch请求
requests.options("<url>"[,**kwargs]):发送options请求

4.Cookie的自动管理:

<s>=requests.session()/<s>=requests.Session()
  #注:requests.Session是1个类,requests.Session()是该类的1个实例
     #requests.session()则是1个方法,功能是返回上述类的1个实例,而不做其他任何操作(见下图)
  #参数说明:
    s:返回的requests.Session类的1个实例

<s>.<type>():发送指定类型的请求
  #参数说明:
    type:通过<s>调用模块中的各个方法,以发送不同类型的请求
      #可为get/post/put/patch/head/options/delete

通过以上2个方法实现Cookies/Headers的自动管理,即自动获取/发送Cookies/Headers而不用手动添加

在这里插入图片描述
5.属性:

示例参见:https://www.cnblogs.com/wupeiqi/articles/6283017.html

<re>.headers:返回响应头
  #参数说明:
    re:发送请求后Server返回的requests.models.Response对象(是字节)

#######################################################################

<re>.encoding[="<coding>"]:查看或设置Response对象的编码方式
<re>.apparent_encoding:返回re使用的编码方式
  #这2种方式的区别在于:前者通过请求头得到,后者通过内容分析得到,通常以前者为准
  #参数说明:
    coding:指定用什么格式进行解码
      #因为re本质上是字节数据,要得到.text需要进行解码

#######################################################################

<re>.text:Response对象的内容,以文本格式返回
<re>.content:Response对象的内容,以二进制格式返回

#######################################################################

<re>.status_code:状态码
  #如200(访问成功),3xx(重定向)

#######################################################################

<re>.cookies:返回的Cookies

<re>.cookies.get_dict():返回Cookies构成的dict

#######################################################################

<re>.url:进行了响应的页面的URL
  #如:如果进行了重定向,会返回重定向到的页面的URL,而不是请求的页面的URL

#实例:
>>> re=requests.get("https://www.autohome.com.cn")
>>> re.url
'https://www.autohome.com.cn/beijing/'

三.Beautifulsoup模块

官方文档:https://www.crummy.com/software/BeautifulSoup/

1.功能:

BeautifulSoup该模块用于接收1个HTML/XML str并对其进行格式化,之后可以使用该模块提供的其他方法快速查找其中的指定元素,从而使
得在HTML/XML中查找指定元素变得简单

2.安装
(1)安装本模块:

pip install bs4

(2)安装第3方解析器:

pip install lxml
pip install html5lib

3.对象
(1)进行格式化(创建BeautifulSoup对象):

<soup>=BeautifulSoup(<HText>[,features="html.parser"]):对HTML/XML文本进行格式化
  #即将str转换成对象(如标签)
  #参数说明:
    HXText:要进行转换的HTML/XML文本
      #通过type()查看得到的结果应为str
    features:指定使用什么解析器进行转换(可用的解析器见下图)
      #也可以作为第2个位置参数传入
      #即使使用html.parser,也最好显式指明,否则有的IDE(如Pycharm)会发出警告
    soup:返回转换后得到的bs4.BeautifulSoup对象
      #最外层是1个<HTML>,其中嵌套着<head>和<body>,再其中继续嵌套

#实例:
import requests,bs4
>>> re=requests.get("https://www.autohome.com.cn/beijing/")
>>> print(type(re))
<class 'requests.models.Response'>
>>> re=requests.get("https://www.autohome.com.cn/beijing/")
>>> print(re)
<Response [200]>
>>> print(type(re))
<class 'requests.models.Response'>
>>> re.encoding=re.apparent_encoding#表示原数据使用的编码方式
>>> print(re.text)#这里只截取了结果中间部位的一小部分
...
<div id="auto-header" class="topbar">
    <div id="auto-header-inner" class="topbar-inner">
        <!-- mini begin -->
        <div class="topbar-mini">
            <div class="mini-main">
...
>>> soup=bs4.BeautifulSoup(re.text,features="html.parser")
>>> print(soup)#这里只截取了结果中间部位的一小部分
...
<script type="text/javascript">
        var _ahs = _ahs || {};
        window._ahs = _ahs;
        (function() {
            if (typeof(pvTrack) !== "undefined") {
...
>>> print(type(soup))
<class 'bs4.BeautifulSoup'>

在这里插入图片描述

#注意:
1.推荐使用lxml,因为效率更高
2.在Python2.7.3/Python3.2.2前的版本,必须安装lxml/html5lib,因为这些Python版本的标准库中内置的HTML解析方法不够稳定
3.如果一段HTML/XML文档格式不正确,那么在不同的解析器中返回的结果可能不同

(2)Tag对象:

<tag>=bs4.element.Tag(name="<tagtype>"[,attrs={"<attr1>":"<v1>"...}]):创建Tag对象
  #参数说明:
    tagtype:指定标签类型,"li"/"div";str
    attrs:指定标签的属性及该属性的值;均为str
      #不能把每个属性都写成关键字参数的形式
    tag:返回创建的Tag对象

#实例:
>>> bs4.element.Tag(name="a",attrs={"id":"123"})
<a id="123"></a>

4.方法

更多实例参见:https://www.cnblogs.com/wupeiqi/articles/6283017.html

(1)查找标签:

<mtag>=<tos>.find(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回<tos>中第1个符合规则的标签
<mtag_li>=<tos>.find_all(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回<tos>中所有符合规则的标签
  #参数说明:
    tos:指定在哪个对象中进行匹配
      #为bs4.BeautifulSoup对象/bs4.element.Tag对象
    tagtype:指定标签类型,"li"/"div";str
      #也可写成关键字参数name="<tagtype>"
      #也可以使用["<tagtype1>","<tagtype2>"...]的形式(或写成关键字参数),用于同时查找多个类型的标签(即各类型间的关系是[或])
      #另外,name属性还支持使用正则表达式/函数进行筛选
    attrs:指定标签的属性及该属性的值(用于筛选);均为str
      #如:attrs={"id":"container","nid":"11111"}
      #也可以写成<attr1>="<v1>",<attr2>="v2"...的形式
      #注意:写成关键字形式时class属性应写为class_="<v1>",否则会和用于定义类的关键字(class)重复
      #所有这些属性都可以写成类似于<tagtype>的列表形式来进行筛选
    recursive:是否递归地进行查找;bool
      #如果为False,则只查找直接子标签(即<soup>中最外层的标签,通常是<html>)
    text:指定标签中的文本内容(用于筛选);str
      #通常直接写在attrs中
    mtag:返回匹配成功的标签
      #如果匹配成功则是bs4.element.Tag对象
      #如果没有匹配成功则是NoneType对象(即None)
    mtag_li:返回匹配成功的标签构成的list
      #无论匹配成功与否都是bs4.element.ResultSet对象,为类list对象
      #然后通过循环/索引获得标签对象

#实例:接 三.3
>>> soup1=soup.find(id="hotcar-1")
>>> print(type(soup1))
<class 'bs4.element.Tag'>
>>> soup11=soup1.find(id="content")
>>> print(soup11)
None
>>> print(type(soup11))
<class 'NoneType'>
>>> soup12=soup1.find("a")
>>> print(type(soup12))
<class 'bs4.element.Tag'>
>>> print(soup12)
<a href="/suv/#pvareaid=3311952">SUV</a>
>>> soup13=soup1.find_all("a")
>>> print(soup13[0])#打印soup13中的第1个元素
<a href="/suv/#pvareaid=3311952">SUV</a>
>>> soup131=soup13[0].find_all("a")#soup13没有.find_all方法,soup13[0]才有
>>> print(soup131)
[]
>>> import re
>>> rep=re.compile("^p")
>>> print(soup.find(name=rep))
<path d="M19.023 19.6l.114-.417.41-.138a2.791 2.791 0 0 0 1.89-2.898l-.246-2.7a2.785 2.785 0 0 0-1.195-2.045l-.29-.2-.051-.347-.003-.018-.95-5.696A2.79 2.79 0 0 0 15.95 2.81h-8.3a2.79 2.79 0 0 0-2.752 2.331l-.95 5.696-.002.018-.052.348-.29.2a2.785 2.785 0 0 0-1.195 2.044l-.245 2.7a2.79 2.79 0 0 0 1.89 2.899l.409.137.114.417a1.891 1.891 0 0 0 3.606.13l.19-.54h6.853l.191.54a1.891 1.891 0 0 0 3.606-.13z"></path>
>>> print(soup.find(name="^p"))#写成位置参数也可
#注意:必须通过re.compile()生成匹配对象才能使用正则表达式,否则"^p"仍会被视为标签类型
None
>>> def func(tag):
...     return tag.has_attr('class') and tag.has_attr('id')
...
>>> print(soup.find(func))#也可以写成关键字参数
<div class="topbar" id="auto-header">
...#此处省略了一部分
<!-- club pop end -->
</div>

##########################################################

<mtag_li>=<tos>.select("<selector>"[,namespaces=None,limit=None,**kwargs]):返回<tos>中所有符合规则的标签构成的list
<mtag>=<tos>.select_one("<selector>"[,namespaces=None,**kwargs]):返回<tos>中第1个符合规则的标签
  #参数说明:tos同上/其他参数参见源码
    selector:指定用于筛选标签的选择器(语法和JQuery中的选择器相同)
    limit:指定返回的list的最大长度

#实例:接 三.3
>>> soup3=soup.select("#floornav-1")#根据id找
>>> soup31=soup3[0].select(".focus-pic")#根据class找
>>> soup311=soup31[0].select("div")#根据标签类型找
>>> soup3111=soup311[0].select("div")
>>> print(soup3111[0].text)
今日焦点

##########################################################

<tag>.find_next(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回下1个标签
<tag>.find_all_next(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回之后所有标签构成的list
<tag>.find_next_sibling(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回下1个同级标签
<tag>.find_next_siblings(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回之后所有同级标签构成的list
<tag>.find_previous(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回上1个标签
<tag>.find_all_previous(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回之前所有标签构成的list
<tag>.find_previous_sibling(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回上1个同级标签
<tag>.find_previous_siblings(["<tagtype>",attrs={"<attr1>":"<v1>"...},recursive=True,text=None]):返回之前所有同级标签构成的list
  #之前/后指的是遍历时的顺序
  #如果没有,返回None/空list
  #参数说明:同<tos>.find_all()

#实例:
>>> html_doc="""<html lang="en">
... <body>
...     <div>ddd</div>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <input>
...     <a></a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> s.find("div").find_next()
<div>
<p>pppp</p>
</div>
>>> s.find("div").find_all_next()
[<div>
<p>pppp</p>
</div>, <p>pppp</p>, <input/>, <a></a>]
>>> s.find("p").find_all_next()
[<input/>, <a></a>]
>>> s.find("p").find_all_previous()
[<div>
<p>pppp</p>
</div>, <div>ddd</div>, <body>
<div>ddd</div>
    bbooddyy
    <div>
<p>pppp</p>
</div>
<input/>
<a></a>
</body>, <html lang="en">
<body>
<div>ddd</div>
    bbooddyy
    <div>
<p>pppp</p>
</div>
<input/>
<a></a>
</body>
</html>]
>>> s.find("p").find_previous_siblings()
[]
>>> s.find("input").find_previous_sibling()
<div>
<p>pppp</p>
</div>
>>> s.find("input").find_previous_sibling().find_previous_siblings()
[<div>ddd</div>]

(2)删除内容:

<re>=<tag>.clear():清空指定标签中的所有内容
  #<tag>本身不会被删除
  #参数说明:
    tag:为bs4.element.Tag对象
    re:返回None

#实例:
>>> import requests,bs4
>>> html_doc="""<html lang="en">
... <body>
...     <a>aaaaa</a>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <a>aa2</a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> re=s.find("body").clear()
>>> print(s)
<html lang="en">
<body></body>
</html>
>>> print(re)
None

##########################################################

<re>=<tag>.decompose():递归地删除所有的标签
  #<tag>本身也会被删除
  #参数说明:
    re:返回None

#实例:
>>> import requests,bs4
>>> html_doc="""<html lang="en">
... <body>
...     <a>aaaaa</a>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <a>aa2</a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> re=s.find("body").decompose()
>>> print(s)
<html lang="en">

</html>
>>> print(re)
None

##########################################################

<rtag>=<tag>.extract():递归地删除所有的标签,并获取被删除的标签
  #参数说明:
    rtag:返回被删除的标签(<tag>)

#实例:
>>> import requests,bs4
>>> html_doc="""<html lang="en">
... <body>
...     <a>aaaaa</a>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <a>aa2</a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> re=s.find("body").extract()
>>> print(s)
<html lang="en">

</html>
>>> print(re)
<body>
<a>aaaaa</a>
    bbooddyy
    <div>
<p>pppp</p>
</div>
<a>aa2</a>
</body>
>>> print(type(re))
<class 'bs4.element.Tag'>

(3)对标签进行转换:

<tag>.encode():将指定标签转换为字节
  #<tag>本身也会被转换

<tag>.encode_contents():将指定标签中的内容转换为字节
  #<tag>本身不会被转换

#实例:
>>> import requests,bs4
>>> html_doc="""<html lang="en">
... <body>
...     <a>aaaaa</a>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <a>aa2</a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> print(s.find("div").encode())
b'<div>\n<p>pppp</p>\n</div>'
>>> print(s.find("div").encode_contents())
b'\n<p>pppp</p>\n'

##########################################################

<tag>.decode():将指定标签转换为str
  #<tag>本身也会被转换;也可以使用str(<tag>)

<tag>.decode_contents():将指定标签中的内容转换为str
  #<tag>本身不会被转换

#实例:接上半部分
>>> print(s.find("div").decode())
<div>
<p>pppp</p>
</div>
>>> print(s.find("div").decode_contents())
              #注意:<p>pppp</p>前后各有1个换行符
<p>pppp</p>

(4)获取指定属性的值:

<v>=<tag>.get("<attr>"):返回指定标签的指定属性的值
  #参数说明:
    attr:指定属性;str
    v:返回tag的attr属性的值;str
      #如果<tag>没有<attr>属性,则返回None

#实例:
>>> doc="""<a href="https://www.google.com"></a>"""
>>> s=bs4.BeautifulSoup(doc)
>>> s.find("a").get("href")
'https://www.google.com'
>>> print(s.find("a").get("nid"))
None

##########################################################

<t>=<tag>.get_text():获取指定标签中的所有文本内容
  #参数说明:
    t:返回的文本内容;str
      #也包括子标签中的文本内容

#实例:
>>> doc="""<a href="https://www.google.com">aaaaa<div>ddd</div></a>"""
>>> s=bs4.BeautifulSoup(doc)
>>> s.find("a").get_text()
'aaaaaddd'#注意:字节点中的文本内容也会被返回

(5)检查标签是否具有指定属性:

<re>=<tag>.has_attr("<attr>"):检查指定标签是否具有指定属性
  #参数说明:
    re:返回检查结果;bool

#实例:接 三.5.(1)
>>> print(s.find("a").has_attr("nid"))
False
>>> print(s.find("a").has_attr("href"))
True

(6)查找标签的索引位置:

<n>=<tag>.index(<tag2>):查找<tag2><tag>中的索引位置
  #参数说明:
    tag2:<tag>中的某个标签
      #<tag2>必须是<tag>的直接子标签才能找到其索引
    n:返回<tag2><tag>中的索引位置
      #如果<tag2>不在<tag>中,直接报错
      #从1开始,且只为奇数,故索引依次为1/3/5...

#实例:
>>> html_doc="""<html lang="en">
... <body>
...     <div>ddd</div>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div><a>aa2</a><input type="text"><b>bbb</b>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> print(tag.index(tag.find("input")))
7
>>> print(tag.index(tag.find("b")))
9
>>> print(tag.index(tag.find("div")))
1
>>> print(tag.index(tag.find("p")))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Euler\AppData\Roaming\Python\Python37\site-packages\bs4\element.py", line 1374, in index
    raise ValueError("Tag.index: element not in tag")
ValueError: Tag.index: element not in tag
>>> print(tag.index(tag.find("h2")))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Euler\AppData\Roaming\Python\Python37\site-packages\bs4\element.py", line 1374, in index
    raise ValueError("Tag.index: element not in tag")
ValueError: Tag.index: element not in tag

(7)插入/替换标签:

<tag>.append(<tag2>):在指定标签中插入标签(会插入到<tag>的最后)
  #注意:①不会在标签后加上换行符 ②<tag2>会被从前原本所属的BeautifulSoup对象中删除
  #参数说明:
    tag2:指定要插入的标签;为bs4.element.Tag对象

#实例:
>>> html_doc="""<html lang="en">
... <body>
... <a>aaa</a>
... <div>ddd</div>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> s.find("body").append(s.find("a"))
>>> s.find("body").append("<a>aaa</a>")
>>> s
<html lang="en">
<body>
                #注意:原本的<a>被删除了(实际上只是在移动标签而没有创建新标签)
<div>ddd</div>  #因此通常会通过bs4.element.Tag()创建1个新的Tag对象
<a>aaa</a>&lt;a&gt;aaa&lt;/a&gt;</body>#注意:不要直接添加tag str
</html>

##########################################################

<tag>.insert(<i>,<tag2>):在指定标签中的指定位置处插入新标签
  #注意:①不会在标签后加上换行符 ②<tag2>会被从前原本所属的BeautifulSoup对象中删除
  #参数说明:
    i:指定插入新标签的位置的索引(或插入后<tag2><tag>中的索引)
      #注意:索引从0开始

#实例:接.append()
>>> s.find("body").insert(0,bs4.element.Tag(name="b"))
>>> s
<html lang="en">
<body><b></b>

<div>ddd</div>
<a>aaa</a>&lt;a&gt;aaa&lt;/a&gt;</body>
</html>

##########################################################

<tag>.insert_before(<tag2>):在指定标签前插入标签
<tag>.insert_after(<tag2>):在指定标签后插入标签
  #注意:①不会在标签后加上换行符 ②<tag2>会被从前原本所属的BeautifulSoup对象中删除

#实例:接.insert()
>>> s.find("div").insert_before(bs4.element.Tag(name="h1"))
>>> s
<html lang="en">
<body><b></b>

<h1></h1><div>ddd</div>
<a>aaa</a>&lt;a&gt;aaa&lt;/a&gt;</body>
</html>

##########################################################

<dtag>=<tag>.replace_with(<tag2>):替换指定标签
  #参数说明:
    tag,tag2:将用<tag2>替换<tag>
    dtag:返回被替换的标签(<tag>)

#实例:接.insert_before/after
>>> s.find("a").replace_with(bs4.element.Tag(name="h2"))
<a>aaa</a>
>>> s
<html lang="en">
<body><b></b>

<h1></h1><div>ddd</div>
<h2></h2>&lt;a&gt;aaa&lt;/a&gt;</body>
</html>

(8)建立标签间的关系:

<tag>.setup([parent=None,previous_element=None,next_element=None,previous_sibling=None,next_sibling=None]):建立/修改<tag>与其他标签的关系
  #即使修改了标签间的关系,在BeautifulSoup对象中仍然不变,只在通过相应的方法查看相应的标签时展示
  #参数说明:
    parent...:分别为父标签//1(同级)标签;均为Tag对象

#实例:
>>> html_doc="""<html lang="en">
... <body>
... <div>ddd<a>aaa</a></div>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> d=s.find("div")
>>> a=s.find("a")
>>> d.setup(previous_sibling=a)
>>> s
<html lang="en">
<body>
<div>ddd<a>aaa</a></div>
</body>
</html>
>>> d.find_previous_sibling()
<a>aaa</a>

(9)将标签包裹起来:

<wtag>=<tag>.wrap(<tag2>):将指定标签包裹起来
  #注意:<tag2>的文本会被放在<tag>之前
  #参数说明:
    tag2:指定用于包裹<tag>的标签
    wtag:返回包裹着<tag><tag2>

#实例:
>>> html_doc="""<html lang="en">
... <body>
... <div>ddd<a>aaa</a></div>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> h=bs4.element.Tag(name="h2")
>>> h.string="hhh"
>>> s.find("div").wrap(h)
<h2>hhh<div>ddd<a>aaa</a></div></h2>
>>> s
<html lang="en">
<body>
<h2>hhh<div>ddd<a>aaa</a></div></h2>
#注意:<h2>中的文本会被放在<div>之前
</body>
</html>

##############################################################

<dtag>=<tag>.unwrap():将指定标签解包
  #即删除<tag>本身,但保留<tag>中的所有内容
  #注意:不仅<tag>的子标签会被保留,<tag>自己的文本内容也会被保留
  #参数说明:
    dtag:返回被删除的标签(即不包含子标签的<tag>)

#实例:接.wrap()
>>> s.find("div").unwrap()
<div></div>
>>> s
<html lang="en">
<body>
<h2>hhhddd<a>aaa</a></h2>
</body>
</html>
>>> s.find("h2").unwrap()
<h2></h2>
>>> s
<html lang="en">
<body>
hhhddd<a>aaa</a>
</body>
</html>

5.属性:

  • 可用于获取属性,也可用于设置属性
<tag>.name:获取指定标签的标签名(即标签类型)
  #返回str
  #参数说明:
    tag:指定标签,为bs4.element.Tag对象

#实例:接 三.4.(1) 前半部分
>>> print(soup1.name)
div
>>> soup1.name="a"
>>> print(soup1.name)
a

##########################################################

<tag>.attrs:获取指定标签的所有属性构成的dict

#实例:接 三.4.(1) 前半部分
>>> print(soup13[0].attrs)#获取所有属性构成的字典
{'href': '/suv/#pvareaid=3311952'}
>>> print(soup13[0].attrs.get("href"))#获得href属性的值
/suv/#pvareaid=3311952
>>> soup13[0].attrs["kkk"]={"vvv"}#当然,原始的文档不会被修改,只有soup13会被修改
>>> print(soup13[0].attrs)
{'href': '/suv/#pvareaid=3311952', 'kkk': {'vvv'}}
>>> del soup13[0].attrs["kkk"]
>>> print(soup13[0].attrs)
{'href': '/suv/#pvareaid=3311952'}

##########################################################

<tag>.children:获得指定标签所有(直接)子节点构成的iterator
  #仅包括<tag>的直接子节点,不包括孙代及之后各代标签
  #节点不只包含标签,也包含文本,每2个标签间的文本都是1个节点(如果不全是空白)
<tag>.descendants:获得指定标签所有后代节点构成的iterator
  #其中的元素都是完整的节点,而不是该节点去除其后代节点后剩余的部分

#实例1:
>>> import bs4
>>> html_doc="""<!DOCTYPE html>
... <html lang="en">
... <head>
...     <meta charset="UTF-8">
...     <title>Title</title>
... </head>
... <body>
...     <a>aaaaa</a>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <a>aa2</a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> re=s.find("body")
>>> print(list(re.children))
['\n', <a>aaaaa</a>, '\n    bbooddyy\n    ', <div>
<p>pppp</p>
</div>, '\n', <a>aa2</a>, '\n']
>>> for tag in re:
...     print(tag,type(tag))
...

 <class 'bs4.element.NavigableString'>#注意:标签节点和文本节点的类型不同
<a>aaaaa</a> <class 'bs4.element.Tag'>#因为可进行的操作不同

    bbooddyy
     <class 'bs4.element.NavigableString'>
<div>
<p>pppp</p>
</div> <class 'bs4.element.Tag'>

 <class 'bs4.element.NavigableString'>
<a>aa2</a> <class 'bs4.element.Tag'>

 <class 'bs4.element.NavigableString'>

#实例2:
>>> import requests,bs4
>>> html_doc="""<!DOCTYPE html>
... <html lang="en">
... <head>
...     <meta charset="UTF-8">
...     <title>Title</title>
... </head>
... <body>
...     <a>aaaaa</a>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <a>aa2</a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> re=s.find("body")
>>> print(list(re.descendants))
#进行递归,找完1个子节点中的所有后代节点再找下1个(对每个子节点的递归同理)
['\n', <a>aaaaa</a>, 'aaaaa', '\n    bbooddyy\n    ', <div>
<p>pppp</p>
</div>, '\n', <p>pppp</p>, 'pppp', '\n', '\n', <a>aa2</a>, 'aa2', '\n']
>>> for tag in re:
...     print(tag,type(tag))
...

 <class 'bs4.element.NavigableString'>
<a>aaaaa</a> <class 'bs4.element.Tag'>

    bbooddyy
     <class 'bs4.element.NavigableString'>
<div>
<p>pppp</p>
</div> <class 'bs4.element.Tag'>

 <class 'bs4.element.NavigableString'>
<a>aa2</a> <class 'bs4.element.Tag'>

 <class 'bs4.element.NavigableString'>
>>> print(list(re.descendants)[4])
<div>       #注意:其中的元素都是完整的节点,而不是该节点去除其后代节点后剩余的部分
<p>pppp</p>
</div>

##########################################################

<tag>.text:返回指定标签中的文本内容(包含子标签中的内容)
  #不包括标签等非文本内容
<tag>.contents:返回指定标签中的所有内容构成的list
<tag>.string:返回指定标签中的文本内容(不包含子标签中的内容)
  #如果通过该属性设置标签中的文本内容,会导致<tag>的子标签被删除
<tag>.stripped_string:递归获得<tag>即其标签的文本内容

#实例:
>>> html_doc="""<html lang="en">
... <body>
...     <div>ddd</div>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <input>
...     <a></a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> s.find_all("div")[1].string
>>> s.find_all("div")[1].text
'\npppp\n'
>>> s.find_all("div")[1].contents
['\n', <p>pppp</p>, '\n']
>>> s.find("div").contents="ascasdasdas"
>>> s.find("div").contents
'ascasdasdas'

##########################################################

<tag>.is_empty_element:判断是否为自闭合标签
  #返回bool

#实例:
>>> html_doc="""<html lang="en">
... <body>
...     <div>ddd</div>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <input>
...     <a></a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> s.find("input").is_empty_element
True
>>> s.find("a").is_empty_element
False

##########################################################

<pe>.next:相当于.next_element
<pe>.next_element:返回下1个节点
<pe>.next_elements:返回之后所有节点构成的生成器
<pe>.next_sibling:返回下1个兄弟节点
<pe>.next_siblings:返回之后所有兄弟节点构成的生成器
<pe>.previous:相当于.previous_element
<pe>.previous_element:返回上1个节点
<pe>.previous_elements:返回之前所有节点构成的生成器
<pe>.previous_sibling:返回上1个兄弟节点
<pe>.previous_siblings:返回之前所有兄弟节点构成的生成器
<pe>.parent:返回直接父节点
<pe>.parents:返回所有祖先节点构成的生成器
  #.next/previous_element(s)功能中所说的之前/后指的是遍历时的顺序
  #参数说明:
    pe:为bs4.element.PageElement对象
      #即表示页面的某部分的对象,如bs4.BeautifulSoup/bs4.element.Tag对象
      #不过,对bs4.BeautifulSoup对象,以上各方法返回的都是None/空生成器

#实例:
>>> html_doc="""<html lang="en">
... <body>
...     <div>ddd</div>
...     bbooddyy
...     <div>
...         <p>pppp</p>
...     </div>
...     <input>
...     <a></a>
... </body>
... </html>"""
>>> s=bs4.BeautifulSoup(html_doc)
>>> print(s.next_element)
None
>>> print(list(s.next_elements))
[]
>>> print(s.find_all("div")[1].next)


>>> print(s.find_all("div")[1].next.next)
<p>pppp</p>
>>> print(list(s.find("p").parents))
[<div>
<p>pppp</p>
</div>, <body>
<div>ddd</div>
    bbooddyy
    <div>
<p>pppp</p>
</div>
<input/>
<a></a>
</body>, <html lang="en">
<body>
<div>ddd</div>
    bbooddyy
    <div>
<p>pppp</p>
</div>
<input/>
<a></a>
</body>
</html>, <html lang="en">
<body>
<div>ddd</div>
    bbooddyy
    <div>
<p>pppp</p>
</div>
<input/>
<a></a>
</body>
</html>]
>>> print(s.find("div").next_sibling)

    bbooddyy

>>> print(list(s.find("html").next_elements))
['\n', <body>
<div>ddd</div>
    bbooddyy
    <div>
<p>pppp</p>
</div>
<input/>
<a></a>
</body>, '\n', <div>ddd</div>, 'ddd', '\n    bbooddyy\n    ', <div>
<p>pppp</p>
</div>, '\n', <p>pppp</p>, 'pppp', '\n', '\n', <input/>, '\n', <a></a>, '\n', '\n']
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值