理数据
前面我们说过了通过 requests 库获取数据,这里我们要说如何处理数据
处理数据我们需要用到一个强大的第三方库——BeautifulSoup !
“美味的汤,绿色的浓汤,在热气腾腾的盖碗里装!谁不愿意尝一尝,这样的好汤?晚餐用的汤,美味的汤!”
BeautifulSoup 库的名字取自刘易斯·卡罗尔在《爱丽丝梦游仙境》里的同名诗歌。就像它在仙境中的说法一样,BeautifulSoup 尝试化平淡为神奇。它通过定位 HTML 标签来格式化和组织复杂的网页源代码,用简单易用的 Python 对象为我们展现出 HTML 结构信息。
处理数据分为两步:
解析数据:将网页源代码解析成 Python 能“读懂”的格式
提取数据:将网页源代码中无关数据过滤掉,只提取出我们所需要的数据
解析数据
我们以豆瓣读书 Top250 为例,它的网址是:https://book.douban.com/top250。
我们来看看如何将其网页源代码解析成 BeautifulSoup 对象:
import requests
from bs4 import BeautifulSoup
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
res = requests.get('https://book.douban.com/top250', headers=headers)
soup = BeautifulSoup(res.text, 'html.parser')
Tips:相比之前我们添加 headers 参数,这是为了应对豆瓣的反爬虫机制。
我们通过 from bs4 import BeautifulSoup 语句导入 BeautifulSoup,然后使用 BeautifulSoup(res.text, 'html.parser') 语句将网页源代码的字符串形式解析成了 BeautifulSoup 对象。
创建 BeautifulSoup 对象时需要传入两个参数,第一个参数是要解析的 HTML 文本,即网站源代码的字符串形式(res.text)。第二个参数是 解析HTML 的解析器,html.parser 是 Python 中内置的解析器,较为简单方便.
我们将网页源代码解析成了 BeautifulSoup 对象,如果我们将他打印出来会发现竟然和原来的网页源代码(也就是 res.text)一模一样!既然都一样,我们何苦费这么大力将网页源代码解析成 BeautifulSoup 对象 呢?
相比字符串,BeautifulSoup 对象 里有很多强大的方法和属性。通过这些方法和属性,我们就能方便快捷地提取出我们所需要的数据。
提取数据
BeautifulSoup 对象 里的方法和属性有很多,我们这里只提及其中最常用的一些,这些足以应付大多数场景。
find() 方法和 find_all() 方法
BeautifulSoup 对象 里的 find() 和 find_all() 是我们提取数据最常用的两个方法。借助它们,我们可以过滤掉 HTML 页面里的无用数据,轻松地找到我们需要的数据。
我们来看一下 find() 和 find_all() 的作用和区别:
我们可以通过例子来更好地理解他们:
假设我们获取到的网页源代码如下:
<div class="content">
<a href="https://douban.com">登录/注册</a>
<h1>豆瓣读书 Top 250</h1>
<div class="artile">
<a href="https://movie.douban.com">豆瓣电影</a>
<div class="item">
<a href="https://book.douban.com/subject/1770782/">追风筝的人</a>
</div>
<div class="item">
<a href="https://book.douban.com/subject/25862578/">解忧杂货店</a>
</div>
<div class="item">
<a href="https://book.douban.com/subject/1084336/">小王子</a>
</div>
</div>
</div>
soup = BeautifulSoup(res.text, 'html.parser')
print(soup.find('a'))
# 输出:<a href="https://douban.com">登录/注册</a>
print(soup.find_all('a'))
# 输出:[
# <a href="https://douban.com">登录/注册</a>,
# <a href="https://movie.douban.com">豆瓣电影</a>,
# <a href="https://book.douban.com/subject/1770782/">追风筝的人</a>,
# <a href="https://book.douban.com/subject/25862578/">解忧杂货店</a>,
# <a href="https://book.douban.com/subject/1084336/">小王子</a>
# ]
它俩的用法基本一样,都是传入 HTML 标签名称,返回符合该 HTML 标签的数据。区别是 find() 方法只返回第一个符合条件的标签,而 find_all() 方法返回所有符合条件的标签列表。他们的返回值分别是 BeautifulSoup 中的 Tag 对象 和由 Tag 对象组成的列表。(后面会提到)
除了传入 HTML 标签名称 外,这两个方法还支持传入 HTML 属性 进行筛选,返回符合条件的数据。举个例子:
# 查找 id='doubanapp-tip' 的 div 标签
soup.find('div', id='doubanapp-tip')
# 查找所有 class='rating_nums' 的 span 标签
soup.find_all('span', class_='rating_nums')
class 和 id 这两个 HTML 属性 具有很强的标识性,因此是数据筛选中最常用的两个属性,我们要重点关注。
Tips:因为 class 是 Python 中定义类的关键字,因此用 class_ 表示 HTML 中的 class。
通过 id、class 等 HTML 属性的筛选,我们就可以快速准确的找到我们需要的数据。当一个条件无法精确定位到我们想要的数据时,我们还可以传入多个 HTML 属性进行筛选,返回同时符合这些条件的数据。
我们再来看个例子:
# 查找 id='doubanapp-tip' 且 class='rating_nums' 的 div 标签
soup.find('div', id='doubanapp-tip', class_='rating_nums')
Tag对象
BeautifulSoup 将 HTML 中的元素封装成了 Tag 对象。和 BeautifulSoup 对象 一样,Tag 对象 里也有 find() 和 find_all() 方法。因此,我们可以不断地调用这两个方法,一层一层地找到我们需要的数据。我们还是以前面的 HTML 代码为例提取其中的书名:
<div class="content">
<a href="https://douban.com">登录/注册</a>
<h1>豆瓣读书 Top 250</h1>
<div class="books">
<a href="https://movie.douban.com">豆瓣电影</a>
<div class="item">
<a href="https://book.douban.com/subject/1770782/">追风筝的人</a>
</div>
<div class="item">
<a href="https://book.douban.com/subject/25862578/">解忧杂货店</a>
</div>
<div class="item">
<a href="https://book.douban.com/subject/1084336/">小王子</a>
</div>
</div>
</div>
我们可以看到,书名在 a 标签 中。但如果直接使用 soup.find_all(‘a’) 的话,第二行的“登录/注册”和第五行的“豆瓣电影”也会被获取到,因此我们需要将这些无效数据过滤掉。
我们分析一下不难发现,书名在 class=“item” 的 div 标签 里的 a 标签 内。我们只要先找到所有 class=“item” 的 div 标签,然后再找到其中的 a 标签 即可,因此我们可以像下面这样来获取书名的数据:
# 找到所有 class_='item' 的 div 标签
items = soup.find_all('div', class_='item')
for i in items:
# 找到 class_='item' 的 div 标签中的 a 标签
print(i.find('a'))
# 输出:
# <a href="https://book.douban.com/subject/1770782/">追风筝的人</a>
# <a href="https://book.douban.com/subject/25862578/">解忧杂货店</a>
# <a href="https://book.douban.com/subject/1084336/">小王子</a>
这样,我们就找到了所有书名的数据。此时返回的还是 Tag 对象。如果我们只想要书名和对应的链接呢?这就用到了 Tag 对象 的 text 属性和 HTML 属性名取值。
items = soup.find_all('div', class_='item')
for i in items:
tag = i.find('a')
# 获取 text 属性
name = tag.text
# 获取 href 属性值
link = tag['href']
print(name, link)
# 输出:
# 追风筝的人 https://book.douban.com/subject/1770782/
# 解忧杂货店 https://book.douban.com/subject/25862578/
# 小王子 https://book.douban.com/subject/1084336/
我们通过 Tag 对象 的 text 属性拿到了 a 标签里的文字内容,即 追风筝的人 等。然后我们通过和字典取值一样的方式,将 HTML 属性名 作为键,得到了对应属性的值。这里是以 href 属性为例,其他的 HTML 属性也同样可以。
我们来总结一下 Tag 对象 的常用属性和方法:
CSS选择器
有没有什么方法可以直接就找到我们需要的数据,而不用多次查找吗?
答案是肯定的,需要用到 CSS 选择器。
在 CSS 选择器中,# 代表 id,. 代表 class。比如:#login 表示 id=‘login’ 的所有元素,.item 表示 class=‘item’ 的所有元素。
我们也可以直接通过标签名选择对应的元素,比如:a 表示所有的 a 元素,p 表示所有的 p 元素。
它们也可以组合在一起,选择同时符合条件的元素,比如:a#login 表示所有 id=‘login’ 的 a 元素,p.item 表示所有 class=‘item’ 的 p 元素,#login.item 表示所有 id=‘login’ 且 class=‘item’ 的元素,.item.book 表示所有 class 同时为 item 和 book 的元素。
需要注意的是,选择同时符合条件的元素,选择器之间不能有空格,如果写成 .item .book 就是另一个意思了。这是新的知识点——子元素选择。
当两个选择器之间加了空格,表示子元素选择。还是以 .item .book 为例,它表示选择所有 class=‘item’ 的元素里面 class=‘book’ 的元素,即嵌套在 class=‘item’ 的元素里面 class=‘book’ 的元素。
这个嵌套可以是任意层级的,只要在里面就行,不要求直接嵌套在第一层。如果只需要直接嵌套在第一层符合条件的元素,可以用 > 分隔。比如:.item > .book。
来看个例子感受一下它们的区别:
from bs4 import BeautifulSoup
html = '''
<div class="item">
<p class="book">小王子</p>
<div class="hot">
<p class="book">追风筝的人</p>
</div>
</div>'''
soup = BeautifulSoup(html, 'html.parser')
print(soup.select('.item.book'))
# 输出:[]
print(soup.select('.item .book'))
# 输出:[<p class="book">小王子</p>, <p class="book">追风筝的人</p>]
print(soup.select('.item > .book'))
# 输出:[<p class="book">小王子</p>]
了解了 CSS 选择器的基本语法后,我们来看看如何在 BeautifulSoup 中使用。
BeautifulSoup 对象 有一个 select() 方法,我们将 CSS 选择器 传进去即可直接找到我们需要的元素。上面查找在 class=“item” 的 div 标签 里的 a 标签 的代码就可以这样写:
items = soup.select('div.item a')
for i in items:
name = i.text
link = i['href']
print(name, link)
# 输出:
# 追风筝的人 https://book.douban.com/subject/1770782/
# 解忧杂货店 https://book.douban.com/subject/25862578/
# 小王子 https://book.douban.com/subject/1084336/
对于静态网页爬虫的过程,可以总结成下图:
我们现在对豆瓣top250中的前25个电影的名字以及名字进行爬取:
import requests
from bs4 import BeautifulSoup
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36 Edg/101.0.1210.32'
}
#首先对网页发出请求并获得响应
req = requests.get('https://movie.douban.com/top250',headers = headers)
#将网页的源代码形式解析
soup = BeautifulSoup(req.text,'html.parser')
#进行元素的第一次提取
result1 = soup.select('.item .pic')
num = 0
for i in result1:
num += 1
name = i.select('a img')[0]['alt']
link = i.select('a')[0]['href']
print(num,' ',name,link)
结果:
文章知识点与官方知识档案匹配,可进一步学习相关知识 , 免费领取有关于java面试题材料和讲解!
原文出处:https://blog.csdn.net/zyb18507175502/article/details/124636025?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-5-124636025-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-5-124636025-null-null.nonecase
提:
安装配置有node环境
一、初始化node项目
在项目的工作目录,执行命令
npm init
初始化参数设置,可以根据情况设置,或者直接全部默认也行:
初始化项目
二、安装express模块
Express是目前最流行的基于Node.js的Web开发框架,可以快速地搭建一个完整功能的网站。
直接通过命令行安装
npm i express --save
G:\app-server>npm i -g express --save
+ express@4.17.1
added 2 packages from 2 contributors and updated 24 packages in 23.892s
三、编写app.js
新建一个app.js文件
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(8080, () => {
console.log(`App listening at port 8080`)
})
在express添加中间件,设置静态资源路径为public,所有的HTML、CSS、JS等文件都放在public下即可。默认访问public下面的index.html
新建index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Web测试平台</title>
</head>
<body>
<h1>Web测试平台</h1>
</body>
</html>
四、启动服务
node app.js
即可运行
G:\app-server>node app.js
App listening at port 8080
访问ip:8080
就可以访问到index.html那个页面了哦。
好了,各位老铁。相信你一定也学会搭建这个服务器环境了哦。
有问题欢迎留言哦。一起学习。
在,大家看到的网站,基本上都是动态网站。但是在20年前,网站基本上都是静态的。静态网页的特点是,网站由一些固定的网页文件和图片文件组成,文件之间通过超级链接进行跳转。如果要更新网站的内容,则需要编辑和更新网页和图片。
对SpringBoot来说,建立一个静态网站是非常容易的事,下面我们也来实现一个简单的静态网站吧。
我们这次的目标是实现一个古诗词网站,可以显示下面几首诗词:
古诗《静夜思》
古诗《赋得古原草送别》
古诗《登鹳雀楼》
古诗《悯农》
古词《念奴娇·赤壁怀古》
古词《青玉案·元夕》
古词《满江红·怒发冲冠》
古词《如梦令·昨夜雨疏风骤》
下面详细描述程序的开发过程。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.flying</groupId>
<artifactId>my_poems</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>my_poems</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>my_poems</finalName>
<plugins>
<!--打包jar-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<!--不打包资源文件,exclude的目录不是src下面的,是以编译结果classes为根目录计算-->
<excludes>
<exclude>*.properties</exclude>
<exclude>*.txt</exclude>
<exclude>*.xml</exclude>
</excludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!--MANIFEST.MF 中 Class-Path 加入前缀-->
<classpathPrefix>my_poems_lib/</classpathPrefix>
<!--jar包不包含唯一版本标识-->
<useUniqueVersions>false</useUniqueVersions>
<!--指定入口类-->
<mainClass>com.flying.my_poems.MyPoemsApplication</mainClass>
</manifest>
<manifestEntries>
<!--MANIFEST.MF 中 Class-Path 加入资源文件目录-->
<Class-Path>./resources/</Class-Path>
</manifestEntries>
</archive>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
<!--拷贝依赖 copy-dependencies-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/my_poems_lib/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!--拷贝资源文件 copy-resources-->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<outputDirectory>${project.build.directory}/resources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<table border="2">
<tr>
<th>古诗</th>
<th>古词</th>
</tr>
<tr>
<td><a href="poems/poem1.html">静夜思</a></td>
<td><a href="lyrics/lyric1.html">念奴娇·赤壁怀古</a></td>
</tr>
<tr>
<td><a href="poems/poem2.html">赋得古原草送别</a></td>
<td><a href="lyrics/lyric2.html">青玉案·元夕</a></td>
</tr>
<tr>
<td><a href="poems/poem3.html">登鹳雀楼</a></td>
<td><a href="lyrics/lyric3.html">满江红·怒发冲冠</a></td>
</tr>
<tr>
<td><a href="poems/poem4.html">悯农</a></td>
<td><a href="lyrics/lyric4.html">如梦令·昨夜雨疏风骤</a></td>
</tr>
</table></body>
</html>
poem1.html的内容是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<a href="/index.html">返回首页</a>
<br/>
<br/>
<h1>静夜思</h1><br/>
李白
<h2>床前明月光,</h2>
<h2>疑是地上霜。</h2>
<h2>举头望明月,</h2>
<h2>低头思故乡。</h2>
</body>
</html>
poem2.html的内容是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<a href="/index.html">返回首页</a>
<br/>
<br/>
<h1>赋得古原草送别</h1><br/>
白居易
<h2>离离原上草,一岁一枯荣。</h2>
<h2>野火烧不尽,春风吹又生。</h2>
<h2>远芳侵古道,晴翠接荒城。</h2>
<h2>又送王孙去,萋萋满别情。</h2>
</body>
</html>
poem3.html的内容是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<a href="/index.html">返回首页</a>
<br/>
<br/>
<h1>登鹳雀楼</h1><br/>
王之涣
<h2>白日依山尽,</h2>
<h2>黄河入海流。</h2>
<h2>欲穷千里目,</h2>
<h2>更上一层楼。</h2>
</body>
</html>
poem4.html的内容是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<a href="/index.html">返回首页</a>
<br/>
<br/>
<h1>悯农</h1><br/>
李绅
<h2>锄禾日当午,</h2>
<h2>汗滴禾下土。</h2>
<h2>谁知盘中餐,</h2>
<h2>粒粒皆辛苦?</h2>
</body>
</html>
8、在src\main\resources\static\lyrics目录中建立lyric1.html、lyric2.html、lyric3.html、lyric4.html,内容分别是:
lyric1.html的内容是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<a href="/index.html">返回首页</a>
<br/>
<br/>
<h1>念奴娇·赤壁怀古</h1><br/>
苏轼
<h2>大江东去,</h2>
<h2>浪淘尽,</h2>
<h2>千古风流人物。</h2>
<h2>故垒西边,</h2>
<h2>人道是,</h2>
<h2>三国周郎赤壁。</h2>
<h2>乱石穿空,</h2>
<h2>惊涛拍岸,</h2>
<h2>卷起千堆雪。</h2>
<h2>江山如画,</h2>
<h2>一时多少豪杰。</h2>
<h2>遥想公瑾当年,</h2>
<h2>小乔初嫁了,</h2>
<h2>雄姿英发。</h2>
<h2>羽扇纶巾,</h2>
<h2>谈笑间,</h2>
<h2>樯橹灰飞烟灭。</h2>
<h2>故国神游,</h2>
<h2>多情应笑我,</h2>
<h2>早生华发。</h2>
</body>
</html>
lyric2.html的内容是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<a href="/index.html">返回首页</a>
<br/>
<br/>
<h1>青玉案·元夕</h1><br/>
辛弃疾
<h2>东风夜放花千树。</h2>
<h2>更吹落、星如雨。</h2>
<h2>宝马雕车香满路。</h2>
<h2>凤箫声动,</h2>
<h2>玉壶光转,</h2>
<h2>一夜鱼龙舞。</h2>
<h2>蛾儿雪柳黄金缕。</h2>
<h2>笑语盈盈暗香去。</h2>
<h2>众里寻他千百度。</h2>
<h2>蓦然回首,</h2>
<h2>那人却在,</h2>
<h2>灯火阑珊处。</h2>
</body>
</html>
lyric3.html的内容是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<a href="/index.html">返回首页</a>
<br/>
<br/>
<h1>满江红</h1><br/>
岳飞
<h2>怒发冲冠,</h2>
<h2>凭栏处、潇潇雨歇。</h2>
<h2>抬望眼、仰天长啸,</h2>
<h2>壮怀激烈。</h2>
<h2>三十功名尘与土,</h2>
<h2>八千里路云和月。</h2>
<h2>莫等闲、白了少年头,</h2>
<h2>空悲切。</h2>
</body>
</html>
lyric4.html的内容是:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>中国诗词网</title>
</head>
<body>
<a href="/index.html">返回首页</a>
<br/>
<br/>
<h1>如梦令</h1><br/>
李清照
<h2>昨夜雨疏风骤,</h2>
<h2>浓睡不消残酒。</h2>
<h2>试问卷帘人,</h2>
<h2>却道海棠依旧。</h2>
<h2>知否,知否?</h2>
<h2>应是绿肥红瘦。</h2>
</body>
</html>
server.port=9000
文章到这里就写完了,谢谢你的阅读。
*请认真填写需求信息,我们会在24小时内与您取得联系。