爬虫之数据解析的三种方式

一,正则表达式解析

re正则就不写了,前面已经写入一篇很详细的正则表达式模块了~

而且,在爬虫中,下面两种方式用的多一些~

正则表达式:https://www.cnblogs.com/peng104/p/9619801.html

大致用法:

pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?src="(.*?)".*?name"><a'+'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>', re.S)
items = re.findall(pattern, html)

二,Xpath解析

简介及安装

简介:XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。

安装:pip install lxml

调用方法:

# 先导包
from lxml import etree# 将html文档或者xml文档转换成一个etree对象,然后调用对象中的方法查找指定的节点
# 1. 本地文件
tree = etree.parse(文件名)
tree.xpath("xpath表达式")# 2. 网络数据
tree = etree.HTML(网页内容字符串)
tree.xpath("xpath表达式")

语法简介

先准备一个HTML格式的字符串

html_doc = """
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div class="d1"><div class="d2"><p class="story"><a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" id="link3">Tillie</a></p></div><div><p id="p1">人生苦短</p><p id="p2">我用python</p></div>
</div><div class="d3"><a href="http://www.baidu.com">baidu</a><p>百度</p>
</div></body>
</html>
"""
变量准备

1,选取节点

nodename     # 选取nodename节点的所有子节点         xpath(‘//div’)         # 选取了所有div节点
/            # 从根节点选取                        xpath(‘/div’)          # 从根节点上选取div节点
//           # 选取所有的当前节点,不考虑他们的位置    xpath(‘//div’)         # 选取所有的div节点
.            # 选取当前节点                        xpath(‘./div’)         # 选取当前节点下的div节点
..           # 选取当前节点的父节点                 xpath(‘..’)            # 回到上一个节点
@            # 选取属性                           xpath(’//@calss’)     # 选取所有的class属性#######################⬇例子⬇######################

ret=selector.xpath("//div")
ret=selector.xpath("/div")
ret=selector.xpath("./div")
ret=selector.xpath("//p[@id='p1']")
ret=selector.xpath("//div[@class='d1']/div/p[@class='story']")

2,谓语

表达式                                         结果
xpath(‘/body/div[1]’)                     # 选取body下的第一个div节点
xpath(‘/body/div[last()]’)                # 选取body下最后一个div节点
xpath(‘/body/div[last()-1]’)              # 选取body下倒数第二个div节点
xpath(‘/body/div[positon()<3]’)           # 选取body下前两个div节点
xpath(‘/body/div[@class]’)                # 选取body下带有class属性的div节点
xpath(‘/body/div[@class=”main”]’)         # 选取body下class属性为main的div节点
xpath(‘/body/div[@price>35.00]’)          # 选取body下price元素值大于35的div节点#######################⬇例子⬇######################

ret=selector.xpath("//p[@class='story']//a[2]")
ret=selector.xpath("//p[@class='story']//a[last()]")

3,通配符

Xpath通过通配符来选取未知的XML元素

表达式                 结果
xpath(’/div/*’)     # 选取div下的所有子节点
xpath(‘/div[@*]’)    # 选取所有带属性的div节点#######################⬇例子⬇######################

ret=selector.xpath("//p[@class='story']/*")
ret=selector.xpath("//p[@class='story']/a[@class]")

4,取多个路径

使用 “|” 运算符可以选取多个路径

表达式                         结果
xpath(‘//div|//table’)    # 选取所有的div和table节点#######################⬇例子⬇######################

ret=selector.xpath("//p[@class='story']/a[@class]|//div[@class='d3']")
print(ret)

5,Xpath轴

轴可以定义相对于当前节点的节点集

轴名称                      表达式                                  描述
ancestor                xpath(‘./ancestor::*’)              # 选取当前节点的所有先辈节点(父、祖父)
ancestor-or-self        xpath(‘./ancestor-or-self::*’)      # 选取当前节点的所有先辈节点以及节点本身
attribute               xpath(‘./attribute::*’)             # 选取当前节点的所有属性
child                   xpath(‘./child::*’)                 # 返回当前节点的所有子节点
descendant              xpath(‘./descendant::*’)            # 返回当前节点的所有后代节点(子节点、孙节点)
following               xpath(‘./following::*’)             # 选取文档中当前节点结束标签后的所有节点
following-sibing        xpath(‘./following-sibing::*’)      # 选取当前节点之后的兄弟节点
parent                  xpath(‘./parent::*’)                # 选取当前节点的父节点
preceding               xpath(‘./preceding::*’)             # 选取文档中当前节点开始标签前的所有节点
preceding-sibling       xpath(‘./preceding-sibling::*’)     # 选取当前节点之前的兄弟节点
self                    xpath(‘./self::*’)                  # 选取当前节点

6,功能函数

使用功能函数能够更好的进行模糊搜索

函数                  用法                                                               解释
starts-with         xpath(‘//div[starts-with(@id,”ma”)]‘)                        # 选取id值以ma开头的div节点
contains            xpath(‘//div[contains(@id,”ma”)]‘)                           # 选取id值包含ma的div节点
and                 xpath(‘//div[contains(@id,”ma”) and contains(@id,”in”)]‘)    # 选取id值包含ma和in的div节点
text()              xpath(‘//div[contains(text(),”ma”)]‘)                        # 选取节点文本包含ma的div节点

Element对象

from lxml.etree import _Element
for obj in ret:print(obj)print(type(obj))  # from lxml.etree import _Element'''
Element对象class xml.etree.ElementTree.Element(tag, attrib={}, **extra)tag:string,元素代表的数据种类。text:string,元素的内容。tail:string,元素的尾形。attrib:dictionary,元素的属性字典。#针对属性的操作clear():清空元素的后代、属性、text和tail也设置为None。get(key, default=None):获取key对应的属性值,如该属性不存在则返回default值。items():根据属性字典返回一个列表,列表元素为(key, value)。keys():返回包含所有元素属性键的列表。set(key, value):设置新的属性键与值。#针对后代的操作append(subelement):添加直系子元素。extend(subelements):增加一串元素对象作为子元素。#python2.7新特性find(match):寻找第一个匹配子元素,匹配对象可以为tag或path。findall(match):寻找所有匹配子元素,匹配对象可以为tag或path。findtext(match):寻找第一个匹配子元素,返回其text值。匹配对象可以为tag或path。insert(index, element):在指定位置插入子元素。iter(tag=None):生成遍历当前元素所有后代或者给定tag的后代的迭代器。#python2.7新特性iterfind(match):根据tag或path查找所有的后代。itertext():遍历所有后代并返回text值。remove(subelement):删除子元素。
'''

三,BeautifulSoup

简介及安装

简介:

    Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
    它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。

安装:pip3 install beautifulsoup4

解析器:

    Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快

官方文档

简单使用

使用方式:可以将一个html文档,转化为BeautifulSoup对象,然后通过对象的方法或者属性去查找指定的节点内容

from bs4 import BeautifulSoup# 转化本地文件
soup = BeautifulSoup(open('本地文件'), 'lxml')# 转化网络文件
soup = BeautifulSoup('字符串类型或者字节类型', 'lxml')# 从文档中获取所有文字内容:
print(soup.get_text())

语法简介

# 1.根据标签名查找- soup.a   只能找到第一个符合要求的标签
# 2.获取属性- soup.a.attrs  获取a所有的属性和属性值,返回一个字典- soup.a.attrs['href']   获取href属性- soup.a['href']   也可简写为这种形式
# 3.获取内容- soup.a.string- soup.a.text- soup.a.get_text()注意:如果标签还有标签,那么string获取到的结果为None,而其它两个,可以获取文本内容
# 4.find:找到第一个符合要求的标签- soup.find('a')  找到第一个符合要求的- soup.find('a', title="xxx")- soup.find('a', alt="xxx")- soup.find('a', class_="xxx")- soup.find('a', id="xxx")
# 5.find_all:找到所有符合要求的标签- soup.find_all('a')- soup.find_all(['a','b']) 找到所有的a和b标签- soup.find_all('a', limit=2)  限制前两个
# 6.根据选择器选择指定的内容select:soup.select('#feng')- 常见的选择器:标签选择器(a)、类选择器(.)、id选择器(#)、层级选择器- 层级选择器:div .dudu #lala .meme .xixi  下面好多级div > p > a > .lala          只能是下面一级注意:select选择器返回永远是列表,需要通过下标提取指定的对象

find_all()

先准备一个HTML格式的字符串

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p id="my p" class="title"><b id="bbb" class="boldest">The Dormouse's story</b>
</p><p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p><p class="story">...</p>
"""
变量准备

1,五种过滤器

字符串、正则表达式、列表、True、方法

from bs4 import BeautifulSoup
soup=BeautifulSoup(html_doc,'lxml')#1、字符串:即标签名
print(soup.find_all('b'))#2、正则表达式
import re
print(soup.find_all(re.compile('^b'))) #找出b开头的标签,结果有body和b标签#3、列表:如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有<a>标签和<b>标签:
print(soup.find_all(['a','b']))#4、True:可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
print(soup.find_all(True))
for tag in soup.find_all(True):print(tag.name)#5、方法:如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
def has_class_but_no_id(tag):return tag.has_attr('class') and not tag.has_attr('id')
print(soup.find_all(has_class_but_no_id))

2、按照类名查找

注意:关键字是class_,class_=value,value可以是五种选择器之一

print(soup.find_all('a',class_='sister')) # 查找类为sister的a标签
print(soup.find_all('a',class_='sister ssss')) # 查找类为sister和sss的a标签,顺序错误也匹配不成功
print(soup.find_all(class_=re.compile('^sis'))) # 查找类为sister的所有标签

3、attrs

print(soup.find_all('p',attrs={'class':'story'}))

4、text

值可以是:字符,列表,True,正则

print(soup.find_all(text='Elsie'))
print(soup.find_all('a',text='Elsie'))

5、limit参数

如果文档树很大那么搜索会很慢.如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量.效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果

print(soup.find_all('a',limit=2))

6、recursive

调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False .

print(soup.html.find_all('a'))
print(soup.html.find_all('a',recursive=False))

tag

像调用 find_all() 一样调用tag find_all() 几乎是Beautiful Soup中最常用的搜索方法,所以我们定义了它的简写方法. BeautifulSoup 对象和 tag 对象可以被当作一个方法来使用~

这个方法的执行结果与调用这个对象的 find_all() 方法相同~

# 下面两行代码是等价的:
soup.find_all("a")
soup("a")# 这两行代码也是等价的:
soup.title.find_all(text=True)
soup.title(text=True)

find

find( name , attrs , recursive , text , **kwargs )

find_all() 方法将返回文档中符合条件的所有tag,尽管有时候我们只想得到一个结果.比如文档中只有一个<body>标签,那么使用 find_all() 方法来查找<body>标签就不太合适, 使用 find_all 方法并设置 limit=1 参数不如直接使用 find() 方法

下面两行代码是等价的:soup.find_all('title', limit=1)
# [<title>The Dormouse's story</title>]
soup.find('title')
# <title>The Dormouse's story</title>

唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果.
find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None .

print(soup.find("nosuchtag"))
# None

soup.head.title 是 tag的名字 方法的简写.这个简写的原理就是多次调用当前tag的 find() 方法:

soup.head.title
# <title>The Dormouse's story</title>
soup.find("head").find("title")
# <title>The Dormouse's story</title>

 

转载于:https://www.cnblogs.com/peng104/p/10317601.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/388409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相对于硬件计算机软件就是,计算机的软件是将解决问题的方法,软件是相对于硬件来说的...

计算机网络管理软件是为计算机网络配置的系统软件。它负责对网络资源进行组织和管理&#xff0c;实现相互之间的通信。计算机网络管理软件包括网络操作系统和数据通信处理程序。前者用于协调网络中各计算机的操作系统及实现网络资源的传递&#xff0c;后者用于网络内的通信&…

数据冒险控制冒险_劳动生产率和其他冒险

数据冒险控制冒险Labor productivity is considered one of the most important indicators of a country’s well-being. However, we don’t know so much about it, let’s try to figure out how it is calculated, and how things are with it in the world (data source:…

如何把一个java程序打包成exe文件,运行在没有java虚

如何把一个java程序打包成exe文件&#xff0c;运行在没有java虚 核心提示&#xff1a;首先&#xff0c;将编译好的程序打包成jar文件&#xff0c;然后做出exe&#xff0c;这样代码就不可见了&#xff1b;但是exe文件在没有安装jre的电脑上不能运行&#xff0c;如果要求客户再去…

Java后端WebSocket的Tomcat实现

原文&#xff1a;https://www.cnblogs.com/xdp-gacl/p/5193279.html 一.WebSocket简单介绍 随着互联网的发展&#xff0c;传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来&#xff0c;随着HTML5的诞生&#xff0c;WebSocket协议被提出&#xff0c;它实现了浏览器与…

加速业务交付,从 GKE 上使用 Kubernetes 和 Istio 开始

原文来源于&#xff1a;谷歌云技术博客 许多企业机构正在把全部或部分 IT 业务迁移到云端&#xff0c;帮助企业更好的运营。不过这样的大规模迁移&#xff0c;在企业的实际操作中也有一定难度。不少企业保存在本地服务器的重要资源&#xff0c;并不支持直接迁移到云端。 另外&a…

knn 邻居数量k的选取_选择K个最近的邻居

knn 邻居数量k的选取Classification is more-or-less just a matter of figuring out to what available group something belongs.分类或多或少只是弄清楚某个事物所属的可用组的问题。 Is Old Town Road a rap song or a country song?Old Town Road是说唱歌曲还是乡村歌曲…

计算机网络中 子网掩码的算法,[网络天地]子网掩码快速算法(转载)

看到一篇很好的资料&#xff0c;大家分享有很多人肯定对设定子网掩码这个不熟悉&#xff0c;很头疼&#xff0c;那么我现在就告诉大家一个很容易算子网掩码的方法&#xff0c;帮助一下喜欢偷懒的人&#xff1a;)大家都应该知道2的0次方到10次方是多少把&#xff1f;也给大家说一…

EXTJS+JSP上传文件带进度条

需求来源是这样的&#xff1a;上传一个很大的excel文件到server&#xff0c; server会解析这个excel&#xff0c; 然后一条一条的插入到数据库&#xff0c;整个过程要耗费很长时间&#xff0c;因此当用户点击上传之后&#xff0c;需要显示一个进度条&#xff0c;并且能够根据后…

android Json详解

Json:一种轻量级的数据交换格式&#xff0c;具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案&#xff08;有点类似于正则表达式 &#xff0c;获得了当今大部分语言的支持&#xff09;&#xff0c;从而可以在不同平台间进行数据交换。JSON采用兼容性…

react实践

React 最佳实践一、 React 与 AJAXReact 只负责处理 View 这一层&#xff0c;它本身不涉及网络请求 /AJAX: 第一&#xff0c;用什么技术从服务端获取数据&#xff1b; 第二&#xff0c;获取到的数据应该放在 react 组件的什么位置。 事实上是有很多的&#xff1a;fetch()、fetc…

什么样的代码是好代码_什么是好代码?

什么样的代码是好代码编码最佳实践 (Coding Best-Practices) In the following section, I will introduce the topic at hand, giving you a sense of what this post will cover, and how each argument therein will be approached. Hopefully, this will help you decide w…

nginx比较apache

话说nginx在大压力的环境中比apache的表现要好&#xff0c;于是下载了一个来折腾一下。 下载并编译安装&#xff0c;我的编译过程有点特别&#xff1a; 1。去除调试信息&#xff0c;修改$nginx_setup_path/auto/cc/gcc这个文件&#xff0c;将 CFLAGS"$CFLAGS -g" …

计算机主板各模块复位,电脑主板复位电路工作原理分析

电源、时钟、复位是主板能正常工作的三大要素。主板在电源、时钟都正常后&#xff0c;复位系统发出复位信号&#xff0c;主板各个部件在收到复位信号后&#xff0c;同步进入初始化状态。如图7-11所示为复位电路的工作原理图&#xff0c;各个十板实现复位的电路不尽相同&#xf…

Docker制作dotnet core控制台程序镜像

(1)首先我们到某个目录下&#xff0c;然后在此目录下打开visual studio code. 2.编辑docker file文件如下: 3.使用dotnet new console创建控制台程序; 4.使用docker build -t daniel/console:dev .来进行打包; 5.启动并运行镜像; 6.我们可以看到打包完的镜像将近2G,因为我们使用…

【362】python 正则表达式

参考&#xff1a;正则表达式 - 廖雪峰 参考&#xff1a;Python3 正则表达式 - 菜鸟教程 参考&#xff1a;正则表达式 - 教程 re.match 尝试从字符串的起始位置匹配一个模式&#xff0c;如果不是起始位置匹配成功的话&#xff0c;match()就返回none。 re.search 扫描整个字符串并…

在Python中使用Twitter Rest API批量搜索和下载推文

数据挖掘 &#xff0c; 编程 (Data Mining, Programming) Getting Twitter data获取Twitter数据 Let’s use the Tweepy package in python instead of handling the Twitter API directly. The two things we will do with the package are, authorize ourselves to use the …

第一套数字电子计算机,计算机试题第一套

《计算机试题第一套》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《计算机试题第一套(5页珍藏版)》请在人人文库网上搜索。1、计算机试题第一套1、计算机之所以能自动运算,就是由于采用了工作原理。A、布尔逻辑。B 储存程序。C、数字电路。D,集成电路答案选B2、“长…

Windows7 + Nginx + Memcached + Tomcat 集群 session 共享

一&#xff0c;环境说明 操作系统是Windows7家庭版&#xff08;有点不专业哦&#xff0c;呵呵&#xff01;&#xff09;&#xff0c;JDK是1.6的版本&#xff0c; Tomcat是apache-tomcat-6.0.35-windows-x86&#xff0c;下载链接&#xff1a;http://tomcat.apache.org/ Nginx…

git 版本控制(一)

新建代码库repository 1、在当前目录新建一个git代码库 git init git init projectname 2、下载一个项目&#xff0c;如果已经有了远端的代码&#xff0c;则可以使用clone下载 git clone url 增加/删除/改名文件 1、添加指定文件到暂存区 git add filename 2、添加指定目录到暂…

rollup学习小记

周末在家重构网关的Npm包&#xff0c;用到了rollup&#xff0c;记下笔记 rollup适合库library的开发&#xff0c;而webpack适合应用程序的开发。 rollup也支持tree-shaking&#xff0c;自带的功能。 package.json 也具有 module 字段&#xff0c;像 Rollup 和 webpack 2 这样的…