爬虫基础知识+豆瓣电影实战

什么是爬虫

        简单来说,爬虫就是获取网页并提取和保存信息的自动化程序,爬虫能够自动请求网页,并将所需要的数据抓取下来。通过对抓取的数据进行处理,从而提取出有价值的信息进行存储使用。
为什么用Python做爬虫
        首先您应该明确,不止 Python 这一种语言可以做爬虫,诸如 Java、C/C++、PHP 都可以用来写爬虫程序,但是相比较而言 Python 做爬虫是最简单的。下面对它们的优劣势做简单对比:
        Java 也经常用来写爬虫程序,但是 Java 语言本身很笨重,代码量很大,因此它对于初学者而言,入门的门槛较高;C/C++ 运行效率虽然很高,但是学习和开发成本高。写一个小型的爬虫程序就可能花费很长的时间,PHP:对多线程、异步支持不是很好,并发处理能力较弱。
        而 Python 语言,其语法优美、代码简洁、开发效率高、支持多个爬虫模块,比如 urllib、requests、Bs4、lxml 等。Python 的请求模块和解析模块丰富成熟,并且还提供了强大的 Scrapy 框架,让编写爬虫程序变得更为简单。因此使用 Python 编写爬虫程序是个非常不错的选择。

编写爬虫注意事项

爬虫是一把双刃剑,它给我们带来便利的同时,也给网络安全带来了隐患。有些不法分子利用爬虫在网络上非法搜集网民信息,或者利用爬虫恶意攻击他人网站,从而导致网站瘫痪的严重后果。关于爬虫的如何合法使用,推荐阅读《中华人民共和国网络安全法》。

因此大家在使用爬虫的时候,要自觉遵守国家法律法规,不要非法获取他人信息,或者做一些危害他人网站的事情。

编写爬虫的流程

       爬虫程序与其他程序不同,它的的思维逻辑一般都是相似的,所以无需我们在逻辑方面花费大量的时间。下面对 Python 编写爬虫程序的流程做简单地说明:
        先由 requests 模块的 get() 方法打开 URL 得到网页 HTML 对象。
        使用浏览器打开网页源代码分析网页结构以及元素节点。
        通过解析库(lxml、BeautifulSoup)或则正则表达式提取数据。
        存储数据到本地磁盘或数据库。

        当然也不局限于上述一种流程。编写爬虫程序,需要您具备较好的 Python 编程功底,这样在编写的过程中您才会得心应手。爬虫程序需要尽量伪装成人访问网站的样子,而非机器访问,否则就会被网站的反爬策略限制,甚至直接封杀 IP,相关知识会在后续内容介绍。
        爬虫程序之所以可以抓取数据,是因为爬虫能够对网页进行分析,并在网页中提取出想要的数据。在学习 Python 爬虫模块前,我们有必要先熟悉网页的基本结构,这是编写爬虫程序的必备知识。
        如果您熟悉前端语言,那么您可以轻松地掌握本节知识。
        网页一般由三部分组成,分别是 HTML(超文本标记语言)、CSS(层叠样式表)和 JavaScript(简称“JS”动态脚本语言),它们三者在网页中分别承担着不同的任务。
        HTML 负责定义网页的内容
        CSS 负责描述网页的布局
        JavaScript 负责网页的行为
接下来我们来一起简单了解一下网页的基础知识。

网页基础知识

网页结构

HTML

        HTML 是网页的基本结构,它相当于人体的骨骼结构。网页中同时带有“<”、“>”符号的都属于 HTML标签。常见的 HTML 标签如下所示:

<!DOCTYPE html> 声明为 HTML5 文档
<html>..</html> 是网页的根元素
<head>..</head> 元素包含了文档的元(meta)数据,如 <meta charset="utf-8"> 定义网页编码格式
为 utf-8。
<title>..<title> 元素描述了文档的标题
<body>..</body> 表示用户可见的内容
<div>..</div> 表示框架
<p>..</p> 表示段落
<ul>..</ul> 定义无序列表
<ol>..</ol>定义有序列表
<li>..</li>表示列表项
<img src="" alt="">表示图片
<h1>..</h1>表示标题
<a href="">..</a>表示超链接

编写如下代码:

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>跟拉拉学编程</title></head>
<body><a href="www.youbafu.com">点击访问</a>
<h1>跟拉拉学Python</h1>
<h2>Python爬虫</h2>
<div><p>认识网页结构</p><ul><li>HTML</li><li>CSS</li></ul>
</div>
</body>
</html>

运行结果如下图所示:

CSS

CSS 表示层叠样式表,其编写方法有三种,分别是行内样式内嵌样式外联样式CSS 代码演示如 下:

<!DOCTYPE html>
<html><head><!-- 内嵌样式 --><style type="text/css"> body{ background-color:yellow; }
p{ font-size: 30px; color: springgreen; } </style><meta charset="utf-8"><title>跟拉拉学编程</title></head><body><!-- h1标签使用了行内样式 --><h1 style="color: blue;">跟拉拉学Python</h1><a href="www.youbafu.com">点击访问</a><h2>Python爬虫</h2><div><p>认识网页结构</p><ul><li>HTML</li><li>CSS</li></ul></div></body>
</html>

运行结果如下图所示:

如上图所示内嵌样式通过 style 标签书写样式表:

<style type="text/css"></style>

而行内样式则通过 HTML 元素的 style 属性来书写 CSS 代码。注意,每一个 HTML 元素,都有 styleclassidnametitle 属性。

外联样式表指的是将 CSS 代码单独保存为以 .css 结尾的文件,并使用 引入到所需页面:

<head>

<link rel="stylesheet" type="text/css" href="mystyle.css">
</head>

当样式需要被应用到多个页面的时候,使用外联样式表是最佳的选择。

JavaScript

        JavaScript 负责描述网页的行为,比如,交互的内容和各种特效都可以使用 JavaScript 来实现。当然 可以通过其他方式实现,比如 jQuery、还有一些前端框架( vueReact ),不过它们都是在“JS”的基础上 实现的。

简单示例:

<!DOCTYPE html>
<html> <head><style type="text/css"> body{ background-color: rgb(220, 226, 226); }</style><meta charset="utf-8"> <title>跟拉拉学编程</title> </head><body><h1 style="color: blue;">跟拉拉学Python</h1> <h2>Python爬虫</h2> <p>点击下方按钮获取当前时间</p><button onclick="DisplayDate()">点击这里</button><p id="time" style="color: red;"> </p><!-- script标签内部编写js代码 --><script>function DisplayDate() { document.getElementById("time").innerHTML = Date()}</script> </div></body> 
</html>

运行结果如下:

        如果用人体来比喻网站结构的话,那么 HTML 是人体的骨架,它定义了人的嘴巴、眼睛、耳朵长在什么位置;CSS 描述了人体的外观细节,比如嘴巴长什么样子,眼睛是双眼皮还是单眼,皮肤是黑色的还是 白色的等;而 JavaScript 则表示人拥有的技能,例如唱歌、打球、游泳等。

        当我们在编写一个爬虫程序前,首先要明确待爬取的页面是静态的,还是动态的,只有确定了页面类 型,才方便后续对网页进行分析和程序编写。对于不同的网页类型,编写爬虫程序时所使用的方法也不尽 相同。

网页形态

静态网页

         静态网页是标准的 HTML 文件,通过 GET 请求方法可以直接获取,文件的扩展名是.html .htm 等,网面中可以包含文本、图像、声音、FLASH 动画、客户端脚本和其他插件程序等。静态网页是网站建设的基础,早期的网站一般都是由静态网页制作的。静态并非静止不动,它也包含一些动画效果,这一点不要误解。

        我们知道,当网站信息量较大的时,网页的生成速度会降低,由于静态网页的内容相对固定,且不需要连接后台数据库,因此响应速度非常快。但静态网页更新比较麻烦,每次更新都需要重新加载整个网页。

        静态网页的数据全部包含在 HTML 中,因此爬虫程序可以直接在 HTML 中提取数据。通过分析静态网页的 URL,并找到 URL查询参数的变化规律,就可以实现页面抓取。与动态网页相比,并且静态网页对搜索引擎更加友好,有利于搜索引擎收录。


动态网页

        动态网页指的是采用了动态网页技术的页面,比如 AJAX(是指一种创建交互式、快速动态网页应用的网页开发技术)、ASP(是一种创建动态交互式网页并建立强大的 web 应用程序)JSP( Java 语言创建动 态网页的技术标准) 等技术,它不需要重新加载整个页面内容,就可以实现网页的局部更新。动态页面使用动态页面技术与服务器进行少量的数据交换,从而实现了网页的异步加载。

        抓取动态网页的过程较为复杂,可以使用前面学习的网页自动化来模拟操作实现数据的爬取。

审查网页元素

        对于一个优秀的爬虫工程师而言,要善于发现网页元素的规律,并且能从中提炼出有效的信息。因此,在动手编写爬虫程序前,必须要对网页元素进行审查。本节将讲解如何使用浏览器审查网页元素。

        浏览器都自带检查元素的功能,不同的浏览器对该功能的叫法不同, 谷歌(Chrome)浏览器称为 ,而 Firefox 则称查看元素,尽管如此,但它们的功却是相同的,本教程推荐使用谷歌(Chrome)浏览 器。

检查百度首页

        下面以检查百度首页为例:首先使用 Chrome 浏览器打开百度,然后在百度首页的空白处点击鼠标右 键(或者按快捷键:F12),在出现的会话框中点击检查,并进行如图所示操作:点击审查元素按钮,然 后将鼠移动至a您想检查的位置,比如百度的输入框,然后单击,此时就会将该位置的代码段显示出来, 如下图所示:

        最后在该代码段处点击右键,在出现的会话框中选择 复制 选项卡,并在二级会话框内选择 复制元 ,如下所示:

<input id="kw" name="wd" class="s    ipt" value="" maxlength="255" autocomplete="off">

        依照上述方法,您可以检查页面内的所有元素。

检查网页结构

        对于爬虫而言,检查网页结构是最为关键的一步,需要对网页进行分析,并找出信息元素的相似性。 下面以 豆瓣电影 Top250 豆瓣电影 Top 250 为例,检查每部影片的 HTML 元素结构。 如下图所示:

第一部影片的html代码段如下所示:

<li><div class="item"><div class="pic"><em class="">1</em><a href="https://movie.douban.com/subject/1292052/"><img width="100" alt="肖申克的救赎"
src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp"
class=""></a></div><div class="info"><div class="hd"><a href="https://movie.douban.com/subject/1292052/" class=""><span class="title">肖申克的救赎</span><span class="title">&nbsp;/&nbsp;The Shawshank
Redemption</span><span class="other">&nbsp;/&nbsp;月黑高飞(港) / 刺激1995(台)
</span></a><span class="playable">[可播放]</span></div><div class="bd"><p class="">导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗
宾斯 Tim Robbins /...<br>1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情</p><div class="star"><span class="rating5-t"></span><span class="rating_num" property="v:average">9.7</span><span property="v:best" content="10.0"></span><span>2564578人评价</span></div><p class="quote"><span class="inq">希望让人自由。</span></p></div></div></div>
</li>

接下来检查第二部影片的html代码,如下所示

<li><div class="item"><div class="pic"><em class="">2</em><a href="https://movie.douban.com/subject/1291546/"><img width="100" alt="霸王别姬" src="https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2561716440.webp" class=""></a></div><div class="info"><div class="hd"><a href="https://movie.douban.com/subject/1291546/" class=""><span class="title">霸王别姬</span><span class="other">&nbsp;/&nbsp;再见,我的妾  /  Farewell My Concubine</span></a><span class="playable">[可播放]</span></div><div class="bd"><p class="">导演: 陈凯歌 Kaige Chen&nbsp;&nbsp;&nbsp;主演: 张国荣 Leslie Cheung / 张丰毅 Fengyi Zha...<br>1993&nbsp;/&nbsp;中国大陆 中国香港&nbsp;/&nbsp;剧情 爱情 同性</p><div class="star"><span class="rating5-t"></span><span class="rating_num" property="v:average">9.6</span><span property="v:best" content="10.0"></span><span>2260298人评价</span></div><p class="quote"><span class="inq">风华绝代。</span></p></div></div></div></li>

经过对比发现,除了每部影片的信息不同之外,它们的 HTML 结构是相同的,比如每部影片都使用<div class="item"></div> 标签包裹起来。这里我们只检查了两部影片,如果在实际编写时,同学们可 以多检查几部,从而确定它们的 HTML 结构是相同的。

提示:通过检查网页结构,然后发现规律,这是编写爬虫程序最为重要的一步。

豆瓣电影实战

以豆瓣电影Top250为例,我们使用上节课学过的正则表达式,结合分析网页元素来爬取电影的简单信 息并存储到Excel中,或者存储为json文件。

同学们再来一起看看每部影片的html代码元素结构:

<li><div class="item"><div class="pic"><em class="">1</em><a href="https://movie.douban.com/subject/1292052/"><img width="100" alt="肖申克的救赎" src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class=""></a></div><div class="info"><div class="hd"><a href="https://movie.douban.com/subject/1292052/" class=""><span class="title">肖申克的救赎</span><span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span><span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span></a><span class="playable">[可播放]</span></div><div class="bd"><p class="">导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情</p><div class="star"><span class="rating5-t"></span><span class="rating_num" property="v:average">9.7</span><span property="v:best" content="10.0"></span><span>3060501人评价</span></div><p class="quote"><span class="inq">希望让人自由。</span></p></div></div></div></li>

        这里假设我们要爬取影片的:电影名、电影别名、导演和演员信息、发行时间、地区、类别、推荐 度、评分、评论数、简介信息,我们可以编写对应的正则表达式,将每部影片的需要信息匹配出来,正则表达式如下所示:

# 正则表达式 匹配规则

pattern = re.compile('<li>.*?"title">(.*?)<' +
'.*?"title">(.*?)<.*?"other">(.*?)<' +

'.*?"bd".*?p class="">(.*?)</p>' + # 注意class后面有=""

'.*?"star".*?rating(.*?)-t' +
'.*?"v:average">(.*?)<' +
'.*?<span>(\d+)' +

代码中用到请求模块 requests pandas 库,需要先安装,在终端(Terminal)里输入:

pip install requests

pip install pandas

import json
import os.path
import pandas as pandas
import requests
import re
import csv
# 设置请求头: 模拟浏览器
headers = {'Host': 'movie.douban.com','Origin': 'movie.douban.com','User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Mobile Safari/537.36',
}
# 正则表达式 匹配规则
pattern = re.compile('<li>.*?"title">(.*?)<' +'.*?"title">(.*?)<.*?"other">(.*?)<' +'.*?"bd".*?p class="">(.*?)</p>' + # 注意class后面有=""'.*?"star".*?rating(.*?)-t' +'.*?"v:average">(.*?)<' +'.*?<span>(\d+)人' +'.*?inq">(.*?)<.*?</li>', re.S)
def get_films(pages=5):films = []for i in range(pages):url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)text = requests.get(url, headers=headers).textfor item in re.findall(pattern, text):print(item)m_info = item[3].replace('&nbsp;', '').strip().split('<br>\n')film = {'电影名': item[0],'别名': item[1].replace('&nbsp;', '').replace(' ', '').strip() +item[2].replace('&nbsp;', '').replace(' ', '').strip(),'导演和演员': m_info[0],'发行时间': m_info[1].split('/')[0].strip(),'地区': m_info[1].split('/')[1].strip(),'类别': m_info[1].split('/')[2].strip(),'推荐度': '.'.join(list(item[4])),'评分': item[5],'评论数': item[6],'简介': item[7]}films.append(film)return filmsdef write_cvs(data):with open(r'data/re_films.csv', 'w', encoding='utf-8') as f:w = csv.DictWriter(f, fieldnames=data[0].keys())w.writeheader()w.writerows(data)def write_excel(data):pdfile = pandas.DataFrame(data)pdfile.to_excel(r'data/re_films.xlsx', sheet_name="豆瓣电影")def write_json(data):s = json.dumps(data, indent=4, ensure_ascii=False)with open(r'data/re_films.json', 'w', encoding='utf-8') as f:f.write(s)def start():data = list(get_films(1))if not os.path.exists('data'):os.mkdir('data')write_json(data)# write_excel(data)# write_cvs(data)if __name__ == '__main__':start()
'推荐度': '.'.join(list(item[4]))

这段代码将 `item[4]` 的每个字符用 `'.'` 连接起来。具体步骤如下:

1. **`list(item[4])`**: 将 `item[4]` 转换为字符列表,其中每个字符都是列表的一个元素。
2. **`'.'.join(...)`**: 将字符列表中的每个字符用 `'.'` 连接起来,生成一个新的字符串。

### 示例

假设 `item[4]` 是 `'hello'`,则:

1. **`list(item[4])`**: `['h', 'e', 'l', 'l', 'o']`
2. **`'.'.join(['h', 'e', 'l', 'l', 'o'])`**: `'h.e.l.l.o'`

最终结果是字符之间用 `'.'` 连接的字符串。

m_info = item[3].replace('&nbsp;', '').strip().split('<br>\n')

这段代码对 item[3] 进行了一系列字符串处理操作:

  1. replace('&nbsp;', ''): 替换字符串中的 &nbsp; 为一个空字符串(即删除所有 &nbsp;)。
  2. strip(): 去除字符串开头和结尾的空白字符(如空格、换行)。
  3. split('<br>\n'): 按 <br>\n 进行分割,返回一个列表,列表中的每个元素是按此分隔符分割出来的子串。

这整个过程将 item[3] 中的 HTML 特殊字符和换行符处理后,拆分成一个子串列表。

pdfile.to_excel(r'data/re_films.xlsx', sheet_name="豆瓣电影")

这段代码将 `pdfile` 数据框(DataFrame)保存为一个 Excel 文件。具体操作如下:

- **`to_excel(...)`**: 这是 Pandas 数据框的一个方法,用于将数据框写入 Excel 文件。
- **`r'data/re_films.xlsx'`**: 指定 Excel 文件的路径和文件名。`r` 表示原始字符串,避免转义字符问题。
- **`sheet_name="豆瓣电影"`**: 指定在 Excel 文件中保存数据的工作表名称为 "豆瓣电影"。

### 示例

如果 `pdfile` 是一个数据框,这段代码会将其保存到名为 `re_films.xlsx` 的 Excel 文件中,并在该文件中创建一个名为 "豆瓣电影" 的工作表。

def write_cvs(data):with open(r'data/re_films.csv', 'w', encoding='utf-8') as f:w = csv.DictWriter(f, fieldnames=data[0].keys())w.writeheader()w.writerows(data)
  1. import csv: 引入 csv 模块,这个模块提供了用于读写 CSV 文件的工具。

  2. def write_cvs(data):: 定义一个名为 write_cvs 的函数,接受一个参数 data,该参数应是一个包含字典的列表。

  3. with open(r'data/re_films.csv', 'w', encoding='utf-8') as f::

    • open(r'data/re_films.csv', 'w', encoding='utf-8'): 打开一个名为 re_films.csv 的文件,如果文件不存在会创建它。'w' 模式表示写入模式,会清空文件中原有的内容。encoding='utf-8' 指定使用 UTF-8 编码。
    • as f:: 将打开的文件对象赋给变量 f,并在 with 语句块结束后自动关闭文件。
  4. w = csv.DictWriter(f, fieldnames=data[0].keys()):

    • csv.DictWriter(f, fieldnames=data[0].keys()): 创建一个 DictWriter 对象,用于将字典数据写入 CSV 文件。fieldnames 参数指定 CSV 文件的列名,这里使用 data[0].keys() 来获取第一个字典的键作为列名。
  5. w.writeheader(): 写入 CSV 文件的表头,表头由 fieldnames 指定的列名组成。

  6. w.writerows(data): 将 data 中的所有字典写入 CSV 文件。data 应该是一个字典列表,每个字典表示一行数据。

课程总结

        本节课正式进入了爬虫的内容,学习巩固了爬虫的一些基础知识,同时还学习了静态网页的相关基础 知识,毕竟爬虫的本质是对网页元素进行分析处理,只有对相关的基础知识牢固掌握了,写起爬虫来才会 更加轻松自如,最后结合正则表达式对豆瓣电影Top250进行了实战爬取。

课后习题

编程题

根据豆瓣电影实战的源码,利用openpyxl库编写write_excel2()函数,并将爬取到的前3页数据利用该函数保存到 data/re_films2.xlsx 中,保存格式如下图:

 

import openpyxl
from openpyxl import Workbook
import json
import os.path
import pandas as pandas
import requests
import re
import csv
# 设置请求头: 模拟浏览器
headers = {'Host': 'movie.douban.com','Origin': 'movie.douban.com','User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Mobile Safari/537.36',
}
# 正则表达式 匹配规则
pattern = re.compile('<li>.*?"title">(.*?)<' +'.*?"title">(.*?)<.*?"other">(.*?)<' +'.*?"bd".*?p class="">(.*?)</p>' + # 注意class后面有=""'.*?"star".*?rating(.*?)-t' +'.*?"v:average">(.*?)<' +'.*?<span>(\d+)人' +'.*?inq">(.*?)<.*?</li>', re.S)
def get_films(pages=3):films = []for i in range(pages):url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)text = requests.get(url, headers=headers).textfor item in re.findall(pattern, text):print(item)m_info = item[3].replace('&nbsp;', '').strip().split('<br>\n')film = {'电影名': item[0],'别名': item[1].replace('&nbsp;', '').replace(' ', '').strip() +item[2].replace('&nbsp;', '').replace(' ', '').strip(),'导演和演员': m_info[0],'发行时间': m_info[1].split('/')[0].strip(),'地区': m_info[1].split('/')[1].strip(),'类别': m_info[1].split('/')[2].strip(),'推荐度': '.'.join(list(item[4])),'评分': item[5],'评论数': item[6],'简介': item[7]}films.append(film)return filmsdef write_excel2(data):# 创建一个工作簿wb = Workbook()ws = wb.activews.title = "豆瓣电影"# 写入表头columns = ['电影名', '别名', '导演和演员', '发行时间', '地区', '类别', '推荐度', '评分', '评论数', '简介']ws.append(columns)# 写入数据for film in data:ws.append([film.get('电影名', ''),film.get('别名', ''),film.get('导演和演员', ''),film.get('发行时间', ''),film.get('地区', ''),film.get('类别', ''),film.get('推荐度', ''),film.get('评分', ''),film.get('评论数', ''),film.get('简介', '')])# 保存到文件wb.save('data/re_films2.xlsx')def start():data = list(get_films(3))  # 获取前3页数据if not os.path.exists('data'):os.mkdir('data')write_excel2(data)if __name__ == '__main__':start()

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

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

相关文章

Java创建线程(5种方法)

操作系统提供api操作线程 线程本身是操作系统提供的&#xff0c;操作系统提供API让我们操作线程&#xff0c;JVM对操作系统api进行了封装&#xff0c;在线程这一部分&#xff0c;就提供了Thread类&#xff0c;表示线程。 创建线程 创建一个MyThread类&#xff08;类的名字不…

六、Maven依赖管理、依赖传递和依赖冲突

1.Maven依赖管理 Maven 依赖管理是 Maven 软件中最重要的功能之一。Maven 的依赖管理能够帮助开发人员自动解决软件包依赖问题&#xff0c;使得开发人员能够轻松地将其他开发人员开发的模块或第三方框架集成到自己的应用程序或模块中&#xff0c;避免出现版本冲突和依赖缺失等…

Open Source, Open Life 第九届中国开源年会论坛征集正式启动

中国开源年会 COSCon 是业界最具影响力的开源盛会之一&#xff0c;由开源社在2015年首次发起&#xff0c;而今年我们将迎来第九届 COSCon&#xff01; 以其独特定位及日益增加的影响力&#xff0c;COSCon 吸引了越来越多的国内外企业、高校、开源组织/社区的大力支持。与一般企…

centos7使用ifconfig查看IP,终端无ens33信息解决办法

1.问题描述 大概有十几天没用虚拟机&#xff0c;最后一次用忘记关闭虚拟机系统了&#xff1b;突然&#xff0c;发现我用远程连接工具&#xff0c;连接不上&#xff0c;去到虚拟机内部查看IP发现终端竟然没有输出enss33地址信息&#xff0c;额&#xff0c;就像下面这样。 2.解决…

50Kg大载重长航时无人机技术详解

1. 机体结构设计 针对50Kg级大载重长航时无人机的设计&#xff0c;机体结构需兼顾轻量化、高强度与高稳定性。通常采用复合材料&#xff08;如碳纤维、玻璃纤维等&#xff09;作为主体材料&#xff0c;这些材料不仅重量轻&#xff0c;而且具有良好的抗疲劳性和耐腐蚀性&#x…

ARP协议(原理,特点,报文格式,具体过程),ARP缓存(有效时间,为什么),ARP欺骗(定向断网,成为中间人),RARP简单介绍

目录 ARP协议 引入 介绍 原理 arp请求/响应 特点 报文格式 硬件类型 协议类型 硬件/协议地址长度 op(操作码) 过程 发送请求并处理 返回响应并处理 总结 arp缓存 介绍 arp表项的有效时间 解释 arp欺骗 介绍 定向断网 基于arp的成为中间人的方式 多向…

0基础学习爬虫系列:Python环境搭建

1.背景 当前网络资源更新非常快&#xff0c;然后对应自己感兴趣的内容&#xff0c;每天盯着刷网站又太费时间。我在尝试借助Ai&#xff0c;搭建一套自己知识抓取更新提醒的系统&#xff0c;这样可以用极少的时间&#xff0c;关注到自己感兴趣的信息。 其实&#xff0c;这套逻辑…

使用 Python 实现粒子群优化的理论与实践

这是关于 PSO 是什么以及如何使用它的教程 欢迎来到雲闪世界。有一个笑话让我笑翻了&#xff1a; “您知道吗&#xff0c;在时钟发明之前&#xff0c;人们必须主动四处走动并询问时间&#xff1f;” 显然&#xff0c;这个笑话无需解释&#xff0c;但如果我们稍微思考一下&…

IOS17.0安装巨魔:TrollRestore巨魔发布

&#x1f47b; TrollRestore 17.0 巨魔发布 15.0 - 16.7 RC&#xff08;20H18&#xff09;和17.0。 官网&#xff1a;https://trollrestore.com/ 下载&#xff1a;https://pan.metanetdisk.com/IOS/%E5%B7%A8%E9%AD%94%E7%8E%A9%E5%AE%B6/TrollRestore.com 使用&#xff1a;ht…

共享单车轨迹数据分析:以厦门市共享单车数据为例(一)

共享单车数据作为交通大数据的一个重要组成部分&#xff0c;在现代城市交通管理和规划中发挥着越来越重要的作用。通过对共享单车的数据进行深入分析&#xff0c;城市管理者和规划者能够获得大量有价值的洞察&#xff0c;这些洞察不仅有助于了解城市居民的日常出行模式&#xf…

希尔排序/选择排序

前言&#xff1a; 本篇主要对常见的排序算法进行简要分析&#xff0c;代码中均以数组 arr[] { 5, 3, 9, 6, 2, 4, 7, 1, 8 } 为例&#xff0c;进行升序排列。 常见的排序算法有如下&#xff1a; 选择排序中&#xff0c;直接选择排序没有任何实际与教育意义&#xff0c;而堆排…

基于Python爬虫的淘宝服装数据分析项目

文章目录 一.项目介绍二.爬虫代码代码分析 三. 数据处理四. 数据可视化 一.项目介绍 该项目是基于Python爬虫的淘宝服装数据分析项目&#xff0c;以致于帮助商家了解当前服装市场的需求&#xff0c;制定更加精确的营销策略。首先&#xff0c;需要爬取淘宝中关于服装的大量数据…

人工智能训练师边缘计算实训室解决方案

一、引言 随着物联网&#xff08;IoT&#xff09;、大数据、人工智能&#xff08;AI&#xff09;等技术的飞速发展&#xff0c;计算需求日益复杂和多样化。传统的云计算模式虽在一定程度上满足了这些需求&#xff0c;但在处理海量数据、保障实时性与安全性、提升计算效率等方面…

MyBatis-SQL-语句执行流程

已查询为例 首先我们可以看到&#xff0c;在查询的时候Mapper对象已经是被代理过后的&#xff1a; 所以会执行invoke方法&#xff0c;其底层实现就是JDK的动态代理&#xff1a; 如下图所示&#xff0c;如果MethodCache里面存在方法&#xff0c;则判断这个方法是否为default方…

Java异常体系----深入讲解

JAVA异常体系 1.error 错误 程序无法处理的异常&#xff0c; 它是由JVM产生和抛出的,比如OutOfMemoryError.ThreadDeath等 示例&#xff1a; public class Test {public static void main(String[] args) {run();}public static void run(){run();} }堆栈溢出&#xff0c;…

Selenium 实现图片验证码识别

前言 在测试过程中&#xff0c;有的时候登录需要输入图片验证码。这时候使用Selenium进行自动化测试&#xff0c;怎么做图片验证码识别&#xff1f;本篇内容主要介绍使用Selenium、BufferedImage、Tesseract进行图片 验证码识别。 环境准备 jdk&#xff1a;1.8 tessdata&…

解决Django会话中的竞态条件

Django 会话中的竞态条件&#xff08;race condition&#xff09;问题通常发生在多个请求几乎同时修改同一个会话数据时&#xff0c;导致数据丢失或数据不一致。这种情况在需要频繁更新会话数据的场景&#xff08;如实时聊天应用、并发请求处理等&#xff09;中尤为常见。 1、问…

20240902-VSCode-1.19.1-部署vcpkg-win10-22h2

20240902-VSCode-1.19.1-部署vcpkg-win10-22h2 软件环境 标签:C++ VSCode mingw gcc13 vcpkg cmake分栏:C++操作系统:Windows10 x64 22h2一、安装VScode-1.19.1 请参考另一篇文章《20240717-VSCode-1.91.1-部署gcc13-C++23-win10-22h2》。 二、安装cmake 本文流程需要安…

Java程序到CPU上执行 的步骤

相信很多的小伙伴在最初学习编程的时候会容易产生一个疑惑❓&#xff0c;那就是编写的Java代码究竟是怎么一步一步到CPU上去执行的呢&#xff1f;CPU又是如何执行的呢&#xff1f;今天跟随小编的脚步去化解开这个疑惑❓。 在学习这个过程之前&#xff0c;我们需要先讲解一些与…

Chrome 浏览器插件获取网页 window 对象(方案三)

前言 最近有个需求&#xff0c;是在浏览器插件中获取 window 对象下的某个数据&#xff0c;当时觉得很简单&#xff0c;和 document 一样&#xff0c;直接通过嵌入 content_scripts 直接获取&#xff0c;然后使用 sendMessage 发送数据到插件就行了&#xff0c;结果发现不是这…