美文网首页初学者python_pycham
python爬虫入门之爬取策略 XPath与bs4实现(五)

python爬虫入门之爬取策略 XPath与bs4实现(五)

作者: 9ba4bd5525b9 | 来源:发表于2019-06-06 15:20 被阅读17次

    在爬虫系统中,待抓取URL队列是很重要的一部分。待抓取URL队列中的URL以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面。而决定这些URL排列顺序的方法,叫做抓取策略。下面重点介绍几种常见的抓取策略:

    1 深度优先遍历策略:

    深度优先遍历策略是指网络爬虫会从起始页开始,一个链接一个链接跟踪下去,处理完这条线路之后再转入下一个起始页,继续跟踪链接。我们以下面的图为例:遍历的路径:A-F-G E-H-I B C D

    深度遍历,栈思路

    2 广度优先遍历策略

    宽度优先遍历策略的基本思路是,将新下载网页中发现的链接直接**待抓取URL队列的末尾。也就是指网络爬虫会先抓取起始网页中链接的所有网页,然后再选择其中的一个链接网页,继续抓取在此网页中链接的所有网页。还是以上面的图为例:遍历路径:A-B-C-D-E-F-G-H-I

    3 页面解析与数据提取

    一般来讲对我们而言,需要抓取的是某个网站或者某个应用的内容,提取有用的价值。内容一般分为两部分,非结构化的数据 和 结构化的数据。

    非结构化数据:先有数据,再有结构,

    结构化数据:先有结构、再有数据

    不同类型的数据,我们需要采用不同的方式来处理。

    非结构化的数据处理

    正则表达式

    HTML 文件

    正则表达式

    XPath

    CSS选择器

    结构化的数据处理

    json 文件 JSON Path 转化成Python类型进行操作(json类) XML 文件 转化成Python类型(xmltodict) XPath CSS选择器 正则表达式

    4 Beautiful Soup

    (1) beautifull soup概述

    官方文档地址:http://www.crummy.com/software/BeautifulSoup/bs4/doc/

    Beautiful Soup 相比其他的html解析有个非常重要的优势,BeautifulSoup将复杂HTML文档转换成一个复杂的树形结构。html会被拆解为对象处理。全篇转化为字典和数组。

    相比正则解析的爬虫,省略了学习正则的高成本.

    相比xpath爬虫的解析,同样节约学习时间成本.

    安装

    #liunx安装apt-get install python-bs4#python包安装pip install beautifulsoup4

    每个节点都是Python对象,我们只用根据节点进行查询 , 归纳为4大对象

    Tag #节点类型

    NavigableString # 标签内容

    BeautifulSoup #根节点类型

    Comment #注释

    (1) 创建对象:

    网上文件生成对象

    soup = BeautifulSoup('网上下载的字符串', 'lxml')

    本地文件生成对象

    soup = BeautifulSoup(open('1.html'), 'lxml')

    (2) tag标签

    格式化输出

    frombs4importBeautifulSoup  soup = BeautifulSoup(html_doc)  print(soup.prettify())#html格式化

    获取指定的tag内容

    soup.p.b#获取p标签中b标签# <b>The Dormouse's story</b>  soup.a# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>soup.title#获取title标签# <title>The Dormouse's story</title>  soup.title.name#获取title标签名# u'title'  soup.title.string#获取title标签内容# u'The Dormouse's story'  soup.title.parent.name#获取title的父节点tag的名称# u'head'  #- 提取tag属性  方法是 soup.tag['属性名称']watsy's blog</a> 

    soup.a['href']

    (3)find与find_all

    find_all(返回一个列表)

    find_all('a')  查找到所有的afind_all(['a', 'span'])  返回所有的a和spanfind_all('a', limit=2)  只找前两个a

    find(返回一个对象)

    find('a'):只找到第一个a标签find('a', title='名字')find('a', class_='名字')#注意1.不能使用name属性查找2.class_后面有下划线3.可以使用自定义属性,比如age

    deffind_all(self, name=None, attrs={}, recursive=True, text=None,limit=None, **kwargs):tag的名称,attrs属性, 是否递归,text是判断内容 limit是提取数量限制 **kwargs 含字典的关键字参数    print(soup.find('p'))# 第一个pprint(soup.find_all('p'))# 所有的p,列表print(soup.find_all(['b','i']))#找列表中任意一个print(soup.find_all('a', attrs={'id':'link2'}))#限制属性为 id: link2print(soup.find_all('a', id='link2'))#关键字形式 id=link2print(soup.find_all('a', limit=2))#class_属性print(soup.find_all('a', class_="sister"))print(soup.find_all('a', text=re.compile('^L')))

    tag名称  soup.find_all('b')# [<b>The Dormouse's story</b>]  正则参数importrefortaginsoup.find_all(re.compile("^b")):#匹配所有以b开头标签print(tag.name)# body  # b  fortaginsoup.find_all(re.compile("t")):      print(tag.name)# html  # title  函数调用defhas_class_but_no_id(tag):returntag.has_attr('class')andnottag.has_attr('id')    soup.find_all(has_class_but_no_id)# [<p class="title"><b>The Dormouse's story</b></p>,  #  <p class="story">Once upon a time there were...</p>,  #  <p class="story">...</p>]  tag的名称和属性查找  soup.find_all("p","title")# [<p class="title"><b>The Dormouse's story</b></p>]  tag过滤  soup.find_all("a")# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,  #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,  #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]  tag属性过滤  soup.find_all(id="link2")# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]  text正则过滤importre  soup.find(text=re.compile("sisters"))# u'Once upon a time there were three little sisters; and their names were\n' 

    (4) select 根据选择器--节点对象

    element  p.class.firstname#id      #firstname属性选择器    [attribute]        [target]    [attribute=value]  [target=blank]层级选择器    element element  div p    element>element  div>p    element,element  div,p

    (5) 节点信息

    获取节点内容    obj.string    obj.get_text()【推荐】节点的属性    tag.name 获取标签名    tag.attrs将属性值作为一个字典返回获取节点属性    obj.attrs.get('title')    obj.get('title')    obj['title']

    5 XPath语法

    XPath 使用路径表达式来选取 XML 文档中的节点或节点集

    安装导入

    importlxmlfromlxmlimportetree

    添加插件

    chrome插件网:http://www.cnplugins.com/

    Ctrl + Shift + X打开或关闭插件

    (1) XPath的安装

    #安装lxml库pip install lxml#导入lxml.etreefromlxmlimportetreeetree.parse()  解析本地html文件  html_tree = etree.parse('XX.html')etree.HTML()  解析网络的html字符串  html_tree = etree.HTML(response.read().decode('utf-8')html_tree.xpath()    使用xpath路径查询信息,返回一个列表

    (2) 选取节点

    (3) 选取元素

    (4) 选取若干路径

    通过在路径表达式中使用"|"运算符,您可以选取若干个路径。

    print('myetree.xpath(//*[@class="item-0"])')# *所有

    print('myetree.xpath(//li[@class="item-0" | //div[@class="item-0"]])')#或运算

    (5) XPath语法总结

    节点查询

        element

    路径查询

        //  查找所有子孙节点,不考虑层级关系

        /  找直接子节点

    谓词查询

        //div[@id]

        //div[@id="maincontent"]

    属性查询

        //@class

    逻辑运算

        //div[@id="head" and @class="s_down"]

        //title | //price

    模糊查询

        //div[contains(@id, "he")]

        //div[starts-with(@id, "he")]

        //div[ends-with(@id, "he")]

    内容查询

        //div/h1/text()

    (6)XPath示例

    实例

    爬取照片操作

    bs4 xpath与正则

    xpath综合运用

    相关文章

      网友评论

        本文标题:python爬虫入门之爬取策略 XPath与bs4实现(五)

        本文链接:https://www.haomeiwen.com/subject/mkhuxctx.html