整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

网页数据如何使用Python的方式进行解析?

网页数据如何使用Python的方式进行解析?

介概述:

使用特定引擎解析网页里面得数据,根据规则提取入库

常见的技术:

正则、xpath、pyquery、Beautiful Soup4

一、正则

开源测试工具 http://tool.oschina.net/regex/

官网:https://docs.python.org/zh-cn/3/library/re.html

.

匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。

\d

匹配一个数字字符。等价于 [0-9]。

\D

匹配一个非数字字符。等价于 [^0-9]。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。

\S

匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

\w

匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。

\W

匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。

1、match

用法: 提取关键参数 比如 token sign 后端返回得签名信息 算法

  • match 方法会尝试从字符串的起始位置匹配正则表达式,如果匹配,就返回匹配成功的结果;如果不匹配,就返回 None
import re
content='Hello 123 456 welcome to world'
print(len(content))
result=re.match('^Hello\s\d\d\d\s\d{3}\s\w{7}', content)
print(result)
print(result.group())
print(result.span())
  • group() 返回被 正则 匹配的字符串
  • start() 返回匹配开始的位置
  • span() 返回一个元组包含匹配 (开始,结束) 的位置

方法

说明

group(num=0)

匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组

groups()

返回一个包含所有小组字符串的元组,从 1 到 所含的小组号

1)匹配数字

import re
content='Hello 123456 welcome to world'
result=re.match('^Hello\s(\d+)\swelcome', content)
print(result)
print(result.group(1))
print(result.span())

2)通用匹配

import re
content='Hello 123 456 welcome to world'
# 匹配所有数据
result=re.match('^Hello.*ng$', content)
# 匹配某某开始到某某结束
result=re.match('^Hello(.*)ng$', content).group(1)
print(result)
print(result.group())
print(result.span())

3)贪婪和非贪婪

  • python默认贪婪模式
  • 在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪
import re
content1='http://xxxxx.com/yyds/baidu'
result2=re.match('http.*com/(.*?)s', content1)
result2=re.match('http.*?com/(.*)s', content1)
print('result1', result1.group())
print('result2', result2.group())

4)修饰符

re.I

使匹配对大小写不敏感

re.L

做本地化识别(locale-aware)匹配

re.M

多行匹配,影响 ^ 和 $

re.S

使 . 匹配包括换行在内的所有字符

re.U

根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.

re.X

该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

import re
# 这个修饰符的作用是匹配包括换行符在内的所有字符。
content='''Hello 1234567 World_This
is a Regex Demo
'''
result=re.match('^He.*?(\d+).*?Demo$', content)
result=re.match('^He.*?(\d+).*?Demo$', content,re.S)
print(result.group())

2、search

用法: 提取数据

re模块中的search函数对整个字符串进行扫描并返回第一个匹配的结果。从左到右进行扫描

1)匹配数据

text='人生苦短,我用pythons'
res1=re.search('python',text)
data='result:{"name":"王五","age":"20"}'
res3=re.search("{.*?}",data)

2)正则提取案例

地址:https://finance.ifeng.com/c/8HzIujEasuH

url='https://finance.ifeng.com/c/8HzIujEasuH'
from utils.base import Spider
res=Spider().fetch(url)
import re
# 不带符号
# text=re.findall('var allData={(.*)};',res.text)
# 带符号
# text=re.findall('var allData\s=\s(.*);',res.text)

3)匹配中文

[\u4e00-\u9fa5]
s='大家晚上好asdasdsad'
aa=re.findall('[\u4e00-\u9fa5]+',s)


二、 Pyquery

环境安装

pip install pyquery

利用它,我们可以直接解析 DOM 节点的结构,并通过 DOM 节点的一些属性快速进行内容提取。

html='''
<div id="cont">
<ul class="slist">
<li class="item-0">web开发</li>
<li class="item-1"><a href="link2.html">爬虫开发</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">数据分析</span></a></li>
<li class="item-1 active"><a href="link4.html">深度学习</a></li>
<li class="item-0"><a href="link5.html">机器学习</a></li>
</ul>
</div>
'''

1、实例演示

from pyquery import PyQuery as pq
doc=pq(html)
print(doc('li'))

2、css选择器

doc=pq(html)
print(doc('#cont .slist li'))
print(type(doc('#cont .slist li')))

3、提取内容

for item in doc('#cont .slist li').items():
    print(item.text())

4、子节点

from pyquery import PyQuery as pq
doc=pq(html)
items=doc('.slist')
print(type(items))
print(items) # 提取节点所有内容
lis=items.find('li') # 获取符合条件的li标签
print(type(lis))
print(lis)

5、 属性获取

from pyquery import PyQuery as pq
doc=pq(html)
a=doc('.item-0.active a')
print(a, type(a))
print(a.attr('href'))

6、遍历提取

doc=pq(html)
a=doc('a')
for s in a.items():
    print(s.attr('href')) # 属性获取
    print(s.text()) # 值获取


三、 xpath

插件下载:https://chrome.zzzmh.cn/index#/search

XPath 的选择功能十分强大,它提供了非常简洁明了的路径选择表达式。另外,它还提供了超过 100 个内建函数,用于字符串、数值、时间的匹配以及节点、序列的处理等。几乎所有我们想要定位的节点,都可以用 XPath 来选择。

官网:https://www.w3.org/TR/xpath/

安装xpath解析库:

pip install lxml

表 3-1 XPath 常用规则

表 达 式

描  述

nodename

选取此节点的所有子节点

/

从当前节点选取直接子节点

//

从当前节点选取子孙节点

.

选取当前节点

..

选取当前节点的父节点

@

选取属性

案例演示

text='''
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a>
</ul>
</div>
'''

1、解析

from lxml import etree
html=etree.HTML(text)
result=etree.tostring(html)
print(result.decode('utf-8'))

2、节点操作

我们一般会用 // 开头的 XPath 规则来选取所有符合要求的节点。这里以前面的 HTML 文本为例,如果要选取所有节点,可以这样实现:

这里使用 * 代表匹配所有节点,也就是整个 HTML 文本中的所有节点都会被获取。可以看到,返回形式是一个列表,每个元素是 Element 类型,其后跟了节点的名称,如 html、body、div、ul、li、a 等,所有节点都包含在列表中了。

result=html.xpath('//*')

3、子节点

result=html.xpath('//li/a')
result=html.xpath('//li/a/text()') # 提取数据
result=html.xpath('//li/a/@href') # 属性值

4、指定节点获取

result=html.xpath('//li[@class="item-0"]/a/text()')
print(result)
# ['first item', 'fifth item']

5、匹配翻页元素

# 最后一个
//div[@class="page"]/a[last()-1]
# 下一页
//div[@class="page"]/a[text()="下一页>"]/@href

6、案例演示

? 说明:提取当前网站的首页标题信息,要求使用xpath解析器

from lxml import etree
url1='https://www.icswb.com/channel-list-channel-162.html'
res4=Spider().fetch(url=url1)
html=etree.HTML(res4.text)
li=html.xpath('//ul[@id="NewsListContainer"]/li')
for i in li:
href=i.xpath('./h3/a/text()')
print(href)


四、 Beautiful Soup

简单来说,BeautifulSoup 就是 Python 的一个 HTML 或 XML 的解析库,我们可以用它来方便地从网页中提取数据,官方的解释如下:

BeautifulSoup 提供一些简单的、Python 式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
BeautifulSoup 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时你仅仅需要说明一下原始编码方式就可以了。
BeautifulSoup 已成为和 lxml、html5lib 一样出色的 Python 解释器,为用户灵活地提供不同的解析策略或强劲的速度。

表 4-1 Beautiful Soup 支持的解析器

解析器

使用方法

优势

劣势

Python 标准库

BeautifulSoup(markup, "html.parser")

Python 的内置标准库、执行速度适中 、文档容错能力强

Python 2.7.3 or 3.2.2) 前的版本中文容错能力差

LXML HTML 解析器

BeautifulSoup(markup, "lxml")

速度快、文档容错能力强

需要安装 C 语言库

LXML XML 解析器

BeautifulSoup(markup, "xml")

速度快、唯一支持 XML 的解析器

需要安装 C 语言库

html5lib

BeautifulSoup(markup, "html5lib")

最好的容错性、以浏览器的方式解析文档、生成 HTML5 格式的文档

速度慢、不依赖外部扩展

通过以上对比可以看出,lxml 解析器有解析 HTML 和 XML 的功能,而且速度快,容错能力强,所以推荐

1、安装

pip install beautifulsoup4

2、demo

from bs4 import BeautifulSoup
# 2个参数 html 文本 解析引擎
soup=BeautifulSoup('<p>Hello world</p>', 'lxml')
print(soup.p.string)

3、节点选择器

直接调用节点的名称就可以选择节点元素,再调用 string 属性就可以得到节点内的文本了,这种选择方式速度非常快。如果单个节点结构层次非常清晰,可以选用这种方式来解析。

下面再用一个例子详细说明选择元素的方法:

html="""
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>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>
"""
from bs4 import BeautifulSoup
soup=BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
print(soup.p)

4、获取属性

每个节点可能有多个属性,比如 id 和 class 等,选择这个节点元素后,可以调用 attrs 获取所有属性:

print(soup.p.attrs)
print(soup.p.attrs['name'])

5、嵌套选择

html="""
<html><head><title>The Dormouse's story</title></head>
<body>
"""
from bs4 import BeautifulSoup
soup=BeautifulSoup(html, 'lxml')
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)

6、select(根据选择器选取指定内容)

标签选择器(a),类选择器(.dudu),id选择器(#lala),组合选择器(a, .dudu, #lala, .meme),层级选择器(div.dudu#lala.meme.xixi 表示下面好多级和 div>p>a>.lala 只能是下面一级 ),伪类选择器(不常用),属性选择器 (input[name=‘lala’])

1)样例

htmls="""
<html>
    <head>
        <title>The Dormouse's story</title>
    </head>
    <body>
        <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" title="xl">
                <span>Elsie</span>
            </a>
            <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> 
            and
            <a href="http://example.com/tillie" class="sister" id="link3" rel="noopener noreferrer ">Tillie</a>
            and they lived at the bottom of a well.
        </p>
        <p class="story">...</p>
"""

2)层级选择器

soup.select('.story > a > span')[0].text

3)id选择器

print(soup.select('#link1'))

4)提取属性

soup.select('#link1')[0].attrs['href']

5)属性选择器

print(soup.select("input[type='password']"))

6)提取实际数据

Web 开发中,解析 HTML 是一个常见的任务,特别是当我们需要从网页中提取数据或操作 DOM 时。掌握 Node.js 中解析 HTML 的各种方式,可以大大提高我们提取和处理网页数据的效率。本文将介绍如何在 Node.js 中解析 HTML。

  • Node.js 是什么?Node.js 如何安装及如何配置环境?一文讲解

基本概念

HTML 解析是指将 HTML 文本转换为可操作的数据结构,通常是 DOM(文档对象模型)。DOM 是一个树状结构,表示了网页的结构和内容,允许我们使用 JavaScript 操作和修改网页。

常用的 HTML 解析方法

以下是在 Node.js 中常用的几种 HTML 解析方法:

1.Cheerio:Cheerio 是一个类似于 jQuery 的库,它可以在服务器端使用 CSS 选择器来解析 HTML 并操作 DOM。它适用于解析静态 HTML 页面。

2.jsdom:jsdom 是一个在 Node.js 中模拟 DOM 环境的库。它能够解析和操作 HTML,同时还支持模拟浏览器环境中的许多特性,如事件处理和异步请求。

3.htmlparser2:htmlparser2 是一个快速的 HTML 解析器,它能够将 HTML 文档解析成 DOM 节点流。它通常用于处理大型 HTML 文档或流式数据。

实践案例:使用 Cheerio 解析 HTML

以下是一个使用 Cheerio 解析 HTML 的实际案例,其中包含基本的路由与请求处理。确保你的开发环境中已经安装了 Node.js 和 npm。

1、首先,创建一个新的文件夹,并在该文件夹中运行以下命令初始化项目:

npm init -y

2、安装所需的依赖库:

npm install express cheerio axios

3、创建一个名为 index.js 的文件,然后编写以下代码:

const express=require('express');
const axios=require('axios');
const cheerio=require('cheerio');  // 引入 cheerio 库,用于解析 HTML

const app=express();
const PORT=3000;

app.get('/', async (req, res)=> {
  try {
    // 使用 Axios 发起 GET 请求获取网页的 HTML 内容
    const response=await axios.get('https://apifox.com/blog/mock-manual/'); // 替换为你想要解析的网页 URL
    const html=response.data;  // 获取响应中的 HTML 内容
    
    const $=cheerio.load(html);  // 将 HTML 文本传递给 cheerio,创建一个类似于 jQuery 的对象
    
    // 使用 cheerio 对象的选择器来获取网页标题,并提取文本内容
    const title=$('title').text();  
    
    res.send(`Title: ${title}`);  // 将标题作为响应发送给客户端
  } catch (error) {
    console.error(error);
    res.status(500).send('An error occurred');  // 发生错误时发送错误响应
  }
});

app.listen(PORT, ()=> {
  console.log(`Server is running on port ${PORT}`);  // 启动服务器并监听指定端口
});

在上述代码中,注释解释了每个关键步骤的作用:

  • 通过 axios.get() 发起 GET 请求,获取网页的 HTML 内容。
  • 使用 Cheerio 的 $=cheerio.load(html) 创建了一个可用于选择 DOM 元素的 Cheerio 对象。
  • 通过 $() 使用类似于 jQuery 的选择器,获取 <title> 元素的文本内容。
  • 最后,将提取的标题作为响应发送给客户端。在这个案例中,我们使用 Express 来创建一个简单的服务器,当访问根路由时,我们使用 Axios 获取网页的 HTML 内容,然后使用 Cheerio 解析并提取网页标题。在浏览器或 API 工具中访问 http://localhost:3000/,你将看到响应。
    • 什么是 axios?如何使用 axios?一文快速入门

提示、技巧与注意事项

  • 在使用 Cheerio、jsdom 或 htmlparser2 时,务必了解它们的文档和用法,以充分利用其功能。
  • 当解析复杂的动态页面时,考虑使用模拟浏览器行为的库,如 Puppeteer。

使用接口工具调试后端接口

Apifox 为例,Apifox=Postman + Swagger + Mock + JMeter,Apifox 支持调试 http(s)、WebSocket、Socket、gRPC、Dubbo 等协议的接口,并且集成了 IDEA 插件。在后端人员写完服务接口时,测试阶段可以通过 Apifox 来校验接口的正确性,图形化界面极大的方便了项目的上线效率。

在本文的例子中,就可以通过 Apifox 来测试接口。新建一个项目后,在项目中选择 “调试模式” ,填写请求地址后即可快速发送请求,并获得响应结果,上文的实践案例如图所示:

总结

Node.js 提供了多种方法来解析 HTML,包括 Cheerio、jsdom 和 htmlparser2。选择适合你需求的库,可以轻松地操作和提取网页内容。

知识扩展:

  • Node.js 中怎么拷贝文件?nodejs 拷贝文件的方法
  • 如何在线建一个 JAVA 的 Spring Boot 项目?Spring Boot 快速入门 Helloworld 示例

参考链接:

  • Cheerio 官方文档:https://cheerio.js.org/
  • jsdom GitHub 仓库:https://github.com/jsdom/jsdom
  • htmlparser2 GitHub 仓库:https://github.com/fb55/htmlparser2

TML全局属性是所有HTML元素共有的属性。它们可以应用于所有元素,尽管它们可能对某些元素没有影响。

HTML属性

HTML元素可以设置属性

属性可以在元素中添加附加信息

属性一般描述于开始标签

属性总是以名称/值对的形式出现,比如:name="value"。

属性和属性值对大小写不敏感。不过,万维网联盟在其HTML4推荐标准中推荐小写的属性/属性值。而新版本的(X)HTML要求使用小写属性。

大多数HTML元素支持的属性:

class:为html元素定义一个或多个类名(classname)(类名从样式文件引入)

id:定义元素的唯一id

style:规定元素的行内样式(inlinestyle)

title:描述了元素的额外信息(作为工具条使用)

HTML超链接及其属性

HTML使用标签<a>来设置超文本链接。超链接可以是一个字,一个词,或者一组词,也可以是一幅图像,您可以点击这些内容来跳转到新的文档或者当前文档中的某个部分。当您把鼠标指针移动到网页中的某个链接上时,箭头会变为一只小手。默认情况下,链接将以以下形式出现在浏览器中:

一个未访问过的链接显示为蓝色字体并带有下划线。

访问过的链接显示为紫色并带有下划线。

点击链接时,链接显示为红色并带有下划线。

如果为这些超链接设置了CSS样式,展示样式会根据CSS的设定而显示。

在标签<a>中使用了href属性来描述链接的地址。

实例

<a href="https://www.kaikeba.com/">访问开课吧</a>1复制代码类型:[html]

上面这行代码显示为:访问开课吧

点击这个超链接会把用户带到开课吧的首页。

使用target属性,你可以定义被链接的文档在何处显示。

实例

<ahref="https://www.kaikeba.com/"target="_blank">访问开课吧</a>  

target="_blank":在新窗口中打开被链接文档。  

target="_self":	默认,在相同的框架中打开被链接文档。  

target="_parent":在父框架集中打开被链接文档。  

target="_top":	在整个窗口中打开被链接文档。  

target=framename:在指定的框架中打开被链接文档。  1234567891011复制代码类型:[html]

HTML图像标签及其属性

在HTML中,图像由<img>标签定义。<img>是空标签,意思是说,它只包含属性,并且没有闭合标签。

要在页面上显示图像,你需要使用源属性(src)。src指"source"。源属性的值是图像的URL地址。

定义图像的语法是:

<imgsrc="url"alt="some_text">  1复制代码类型:[html]

URL指存储图像的位置。

alt属性用来为图像定义一串预备的可替换的文本。在浏览器无法载入图像时,替换文本属性告诉读者她们失去的信息。此时,浏览器将显示这个替代性的文本而不是图像。为页面上的图像都加上替换文本属性是个好习惯,这样有助于更好的显示信息,并且对于那些使用纯文本浏览器的人来说是非常有用的。

height(高度)与width(宽度)属性用于设置图像的高度与宽度。属性值默认单位为像素。

<imgsrc="logo.jpg"alt="kaikeba"width="300"height="120">  1复制代码类型:[html]

提示:指定图像的高度和宽度是一个很好的习惯。如果图像指定了高度宽度,页面加载时就会保留指定的尺寸。如果没有指定图片的大小,加载页面时有可能会破坏HTML页面的整体布局。

开课吧广场-人才学习交流平台