python爬虫(网页解析)

目录

了解:

参考图

介绍

bs4库:

解析器:

解析方法

代码示例

lxml库:

解析器

解析方法

代码示例

了解:

参考图

(1) html解析器:

(2) 解析方式: 

介绍

### 前言:
    网页解析即抓取我们想要数据(舍弃其他数据)。
    在python中我们可以通过以下方式去解析抓取:正则表达式、BeautifulSoup、XPath。
    


### 解析方式对比:
参考上图表
(1) 正则表达式
    抓取效率:正则表达式的抓取效率最高,但是需要编写正确的正则表达式,且在处理复杂的HTML文档时容易出错。
    使用难度:正则表达式的使用难度较高,需要掌握正则表达式的语法和规则,以及HTML文档的结构和特点,需要较强的技术功底。
    可靠性:正则表达式的可靠性不如其他两种方式,特别是在处理复杂的HTML文档时容易出错。
(2) BeautifulSoup
    抓取效率:BeautifulSoup的抓取效率相对较低,但可以处理复杂的HTML文档,查找元素的速度较快,对于一些动态加载的网页也能够很好的支持。
    使用难度:BeautifulSoup的使用难度较低,语法简单,易于上手,适合初学者和快速开发。
    可靠性:BeautifulSoup的可靠性较高,可以处理复杂的HTML文档,也可以容错处理,避免了正则表达式的不稳定性。
(3) XPath
    抓取效率:XPath的抓取效率较高,可以处理复杂的HTML文档,查找元素的速度较快。
    使用难度:XPath的使用难度较高,需要掌握XPath的语法和规则,适合有一定技术功底的开发者。
    可靠性:XPath的可靠性较高,可以处理复杂的HTML文档,语法规则相对稳定,也可以容错处理。
(4) 总结:
    综合来看,对于初学者和一些简单的网页抓取任务,建议使用BeautifulSoup作为解析库,它易于上手,语法简单,也比较稳定和可靠。对于复杂的网页抓取任务,可以考虑使用XPath或正则表达式,在效率和可靠性之间进行权衡。
    注意,Xpath只是一种解析方式概念(并不是具体的库或模块),实现Xpath方式的是使用lxml库。

bs4:

解析器:

### 解析器:
BeautifulSoup支持以下几种解析器(参考图表):
    (1) Python标准库中的解析器可选值:'html.parser'和'xml'
        具体:html.parser.HTMLParser和xml.etree.ElementTree
        优点:不需要安装任何第三方库,适用于简单的HTML或XML文档解析
        缺点:解析速度较慢,不支持Xpath语法
    (2) lxml解析器可选值:'lxml'
        具体:lxml.etree.XMLParser
        优点:速度非常快,支持Xpath语法,基于C语言编写
        缺点:需要安装lxml库,
    (3) html5lib解析器可选值:'html5lib'
        具体:html5lib.html5parser.HTMLParser
        优点:能够解析所有的HTML和XML文档,能够正确处理文档中的嵌套标签
        缺点:解析速度最慢,需要安装html5lib库
    综上所述,如果需要解析速度较快且支持Xpath语法,则使用lxml解析器是最好的选择;如果需要解析的文档比较复杂,则使用html5lib解析器;如果解析的文档比较简单,则使用Python标准库中的html.parser或xml解析器即可。

### 使用解析器:
    BeautifulSoup(html,features)
    features即可以接受描述解析器的"字符串参数",然后内部自动调用对应的解析器(前面解析器中已经介绍)
    可选值:'html.parser'、'xml'、'lxml'、'html5lib'
    返回:bs4.BeautifulSoup对象

### bs4.BeautifulSoup对象的相关方法:
    因为其继承了bs4.element.Tag,所以可以参考下面的bs4.element.Tag对象常用方法,这里仅对新方法进行补充。
    new_tag(name, attrs=None):创建一个新的标签对象,返回bs4.element.Tag对象。
    new_string(text, parent=None):创建一个新的文本节点对象,返回bs4.element.NavigableString对象
    prettify():将BeautifulSoup对象的标签树重新格式化,以便于查看和验证。
    replace_with(replacement):用指定的标签或字符串替换当前标签,返回被替换的标签。
    insert_before(new_tag):在当前标签之前插入一个新的标签,返回被插入的标签。
    insert_after(new_tag):在当前标签之后插入一个新的标签,返回被插入的标签。
    encode(encoding=None, formatter=None):将BeautifulSoup对象转换为字节流
    decode(encoding=None, formatter=None):将字节流转换为BeautifulSoup对象。

解析方法

参考图:

(1) bs4.element.Tag常用方法:

(2) 标签操作:

详细介绍

### 以下为相关的bs4.element.Tag对象常用方法(参考图表):
    注意,以下方法中有的返回依然是bs4.element.Tag对象或者bs4.element.Tag对象列表,所以我们可以链式使用。
    find_all(name, attrs): 在当前标签的后代节点中查找符合条件的所有标签,返回bs4.element.Tag对象列表。
    select(css_selector): 使用CSS选择器语法查找符合条件的所有标签,返回bs4.element.Tag对象列表。
    contents: 获取当前标签的所有子节点(包括自身的文本节点),返回bs4.element.Tag对象列表。
    select_one(css_selector): 使用CSS选择器语法查找符合条件的第一个标签,并返回bs4.element.Tag对象。
    parent: 获取当前标签的父节点,返回bs4.element.Tag对象。
    next_sibling: 获取当前标签的下一个兄弟节点,返回bs4.element.Tag对象。
    previous_sibling: 获取当前标签的上一个兄弟节点,返回bs4.element.Tag对象。
    extract(): 将当前标签从文档中移除,返回bs4.element.Tag对象。
    get(name): 获取当前标签的指定属性值,返回字符串。
    text: 获取当前标签的文本内容,返回字符串。
    name: 获取当前标签的名称,返回字符串。
    get_text(separator, strip): 获取当前标签及其后代节点的所有文本内容,返回字符串。
    has_attr(name): 判断当前标签是否包含指定的属性,返回布尔值。
    has_class(name): 判断当前标签是否包含指定的CSS类,返回布尔值。
    has_key(key): 判断当前标签是否包含指定的属性,返回布尔值。
    attrs: 获取当前标签的所有属性,返回字典。
    replace_with(replacement): 将当前标签替换为指定的标签或字符串。
    decompose(): 删除当前标签及其所有后代节点。
    insert(position, tag): 在当前标签的指定位置插入一个新的标签。


        
### 以下为常用标签操作(这里单独整理出来,参考脑图):
    name:获取或设置标签的名称。
    string 或 text:获取或设置标签的文本内容。
    attrs:获取或设置标签的属性。
    get(attr_name):获取标签属性值。
    has_attr(attr_name):判断标签中是否存在指定属性。
    find(tag_filter, attrs_filter):查找文档中第一个与指定标签名和属性匹配的标签。
    find_all(tag_filter, attrs_filter):查找文档中所有与指定标签名和属性匹配的标签。
    find_parent(tag_filter, attrs_filter):获取单个祖先标签。
    find_parents(tag_filter, attrs_filter):查找标签的所有祖先标签。
    find_next_sibling(tag_filter, attrs_filter):查找标签的下一个兄弟标签。
    find_previous_sibling(tag_filter, attrs_filter):查找标签的上一个兄弟标签。
    find_next_siblings(tag_filter, attrs_filter):查找标签后面的所有兄弟标签。
    find_previous_siblings(tag_filter, attrs_filter):查找标签前面的所有兄弟标签。
    contents 或 children:获取标签的所有子节点,返回一个列表类型。
    next_sibling 或 next:获取后面的兄弟标签。
    previous_sibling 或 previous:获取上前面的兄弟标签。
    append(tag):追加子节点
    extend(tag_list):追加多个子节点
    insert(index, tag_or_text):插入子节点。
    replace_with(new_tag):将当前标签替换为一个新的标签,并返回当前标签,结合soup.prettify()。
    unwrap():将当前标签的所有子标签移动到当前标签的父标签中,并删除当前标签。
    clear(): 清空标签。
    extract():将当前标签从文档中删除,并返回当前标签。
    decompose():将当前标签从文档中删除,并销毁当前标签及其子标签的所有内容。

代码示例

(1) 'html.parser'+ find_all:
    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html, 'html.parser')
    p_tags = soup.find_all('p', {'class':'content'})
    for p in p_tags:
        print(p.text)
        
(2) 'html.parser' + select
    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html, 'html.parser')
    p_tags = soup.select('p.content')
    for p in p_tags:
        print(p.text)
        
(3) 'lxml' + select(推荐):
    soup = BeautifulSoup(html, 'lxml')
    注意,该方式只能是在下载了lxml第三方库的前提下使用,否则会出现异常。通过该方式能够加快解析速度,因为BeautifulSoup支持python标准的"html.parser"和html5lib库的"html5lib"解析方式都比较慢 
        
(4) 总结:
    推荐使用方式:BeutifulSoup + lxml + select

lxml:

解析器

###  lxml解析器
(1) 以下为介绍内容:
    在lxml中用于解析网页的解析器主要在lxml.etree模块中。
    当然lxml在除了lxml.etree模块外还有其他的解析器,但暂不在学习范围内。
    
(2) 如下为etree模块的解析器(参考图表):
    etree.XMLParser:使用 lxml 库的 XML 解析器。
    etree.HTMLParser:使用 lxml 库的 HTML 解析器。
    etree.ElementSoup:使用 BeautifulSoup 库的 HTML 解析器。
    etree.C14NParser:使用 lxml 库的 Canonical XML 解析器。
    etree.FastParser:使用 lxml 库的快速解析器。
    etree.TreeBuilder:使用 lxml 库的树构建器。

  ### 使用解析器
    etree.HTML(html,parser=None)
    返回: lxml.etree._Element
    parser参数即可以传入具体的解析器对象,如果没有传入则默认使用html.parser.HTMLParser(python标准库)。
    注意:etree.HTML方法只能使用etree模块中实现的解析器对象,不能再使用其他库的解析器。

解析方法

### 以下为lxml.etree._Elemen对象的常用方法(其他结合下面标签操作补充):
    注意对于返回类型依然为lxml.etree._Element类型时,我们可以进行链式操作。
    findall(tag):查找元素的所有子元素,返回lxml.etree._Elemen列表。
    xpath(xpath_express):使用XPath语法查找元素,返回lxml.etree._Element列表或字符串列表。
    getchildren():获取元素的所有子元素,返回lxml.etree._Element列表。
    find(tag):查找元素的第一个子元素,返回lxml.etree._Element。
    getparent():获取元素的父元素,返回一个lxml.etree._Element。
    getnext():获取元素的下一个兄弟元素,返回一个lxml.etree._Element。
    getprevious():获取元素的前一个兄弟元素,返回一个lxml.etree._Element。
    makeelement(tag, attrib=None, nsmap=None):创建标签,返回lxml.etree._Element。
    getroottree():获取元素所在文档的根元素,返回一个lxml.etree._ElementTree。
    text:获取元素的文本内容,返回一个字符串。
    tag:获取元素的标签名,返回一个字符串。
    get(tag):获取元素的指定属性值,返回字符串或None。
    attrib:获取元素的所有属性,返回字典。
    append(tag):追加子标签,返回None。
    remove(tag):删除子标签,返回None。

### xpath和findall对比:

    无论是xpath方法还是findall方法都能使用Xpath表达式。
    xpath更加灵活实用,区别于findall方法(只能查找到元素标签级别),xpath方法可以获取元素标签的属性值、文本、子元素等等。
    xpath更加高效,xpath内部使用了编译后的XPath表达式来查找元素;而findall内部使用的是正则表达式来匹配元素,效率较低。
    xpath一定可以替代findall,但findall不一定能替代xpath,所以建议使用xpath即可。


    
### 标签(lxml.etree._Element对象)操作(参考脑图):
    创建标签:etree.createelement(tag_name,attr_dict)
    创建标签:etree.Element(tag_name,attr_dict)
    获取/修改标签文本内容:tag.text
    获取标签属性:tag.get(attr_name)
    设置/修改标签属性:tag.set(attr_name,attr_value)
    获取/修改标签属性:tag.attrib
    获取标签属性:tag.keys()
    获取标签属性值:tag.values()
    获取子标签:tag.getchildren()
    获取后面的兄弟标签:tag.getnext()
    获取前面的兄弟标签:tag.getprevious()
    获取父标签:tag.getparent()
    查看标签:etree.tostring(tag,encoding=None,method='html',pretty_print=False)
    追加子标签:tag.append(subtag)
    追加多个子标签:tag.entend(*subtag)
    追加子标签:sub_tag = etree.SubElement(tag,subtag_name,attr_dict)
    指定位置插入标签:tag.insert(index,tag)
    后面添加兄弟标签:addnext(tag)
    前面添加兄弟标签:addprevious(tag)
    替换子标签:tag.replace(subtag,new_tag)
    删除子标签:tag.remove(subtag)
    清空标签:tag.clear()

代码示例

(1) etree.HTMLParser + findall:
    from lxml import etree

    root = etree.HTML(html,parser=etree.HTMLParser())	
    p_tags = root.findall('//p[@class="content"]')
    for p in p_tags:
        print(p.text)
        
(2) etree.XMLParser + xpath:
    from lxml import etree

    root = etree.HTML(html,parser=etree.XMLParser())
    p_tags = root.xpath('//p[@class="content"]')
    for p in p_tags:
        print(p.text)

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值