欢迎关注我的公众号:高级农民工 ,博客:高级农民工,阅读体验更好。
摘要 :从零介绍怎么写一个爬虫实战。
作者 | Jack Cui
来源 | https://cuijiahua.com/blog/2017/10/spider_tutorial_1.html
一、前言
强烈建议: 请在电脑的陪同下,阅读本文。本文以实战为主,阅读过程如稍有不适,还望多加练习。
本文的实战内容有:
网络小说下载(静态网站)
优美壁纸下载(动态网站)
爱奇艺 VIP 视频下载
二、网络爬虫简介
网络爬虫,也叫网络蜘蛛(Web Spider)。它根据网页地址(URL)爬取网页内容,而网页地址(URL)就是我们在浏览器中输入的网站链接。比如:https://www.baidu.com/,它就是一个 URL。
在讲解爬虫内容之前,我们需要先学习一项写爬虫的必备技能:审查元素(如果已掌握,可跳过此部分内容) 。
1、审查元素
在浏览器的地址栏输入 URL 地址,在网页处右键单击,找到检查。(不同浏览器的叫法不同,Chrome 浏览器叫做检查,Firefox 浏览器叫做查看元素,但是功能都是相同的)
我们可以看到,右侧出现了一大推代码,这些代码就叫做 HTML。什么是 HTML?举个容易理解的例子:我们的基因决定了我们的原始容貌,服务器返回的 HTML 决定了网站的原始容貌。
为啥说是原始容貌 呢?因为人可以整容啊!扎心了,有木有?那网站也可以"整容"吗?可以!请看下图:
我能有这么多钱吗?显然不可能。我是怎么给网站"整容"的呢?就是通过修改服务器返回的 HTML 信息。我们每个人都是"整容大师",可以修改页面信息。我们在页面的哪个位置点击审查元素,浏览器就会为我们定位到相应的 HTML 位置,进而就可以在本地更改 HTML 信息。
再举个小例子: 我们都知道,使用浏览器"记住密码"的功能,密码会变成一堆小黑点,是不可见的。可以让密码显示出来吗?可以,只需给页面"动个小手术"!以淘宝为例,在输入密码框处右键,点击检查。
可以看到,浏览器为我们自动定位到了相应的 HTML 位置。将下图中的 password 属性值改为 text 属性值(直接在右侧代码处修改 ):
我们让浏览器记住的密码就这样显现出来了:
说这么多,什么意思呢?浏览器就是作为客户端从服务器端获取信息,然后将信息解析,并展示给我们的。 我们可以在本地修改 HTML 信息,为网页"整容",但是我们修改的信息不会回传到服务器,服务器存储的 HTML 信息不会改变。刷新一下界面,页面还会回到原本的样子。这就跟人整容一样,我们能改变一些表面的东西,但是不能改变我们的基因。
2、简单实例
网络爬虫的第一步就是根据 URL,获取网页的 HTML 信息。 在 Python3 中,可以使用urllib.request 和requests 进行网页爬取。
urllib 库是 python 内置的,无需我们额外安装,只要安装了 Python 就可以使用这个库。 requests 库是第三方库,需要我们自己安装。这个库强大好用,所以本文使用 requests 库获取网页的 HTML 信息。requests 库的 github 地址:https://github.com/requests/requests
(1)requests 安装
在 cmd 中,使用如下指令安装 requests:
pip install requests
requests 库的基础方法如下:
官方中文教程地址:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html
requests 库的开发者为我们提供了详细的中文教程,查询起来很方便。本文不会对其所有内容进行讲解,摘取其部分使用到的内容,进行实战说明。
首先,让我们看下 requests.get()方法,它用于向服务器发起 GET 请求,不了解 GET 请求没有关系。我们可以这样理解:get 的中文意思是得到、抓住,那这个 requests.get()方法就是从服务器得到、抓住数据,也就是获取数据。让我们看一个例子(以 www.gitbook.cn 为例)来加深理解:
# -*- coding:UTF-8 -*-
import requests
if __name__ == '__main__':
target = 'http://gitbook.cn/'
req = requests.get(url=target)
print(req.text)
requests.get()方法必须设置的一个参数就是 url,因为我们得告诉 GET 请求,我们的目标是谁,我们要获取谁的信息。运行程序看下结果:
左侧是我们程序获得的结果,右侧是我们在 www.gitbook.cn 网站审查元素获得的信息。我们可以看到,我们已经顺利获得了该网页的 HTML 信息。这就是一个最简单的爬虫实例,可能你会问,我只是爬取了这个网页的 HTML 信息,有什么用呢?客官稍安勿躁,接下来进入我们的实战正文。
三、爬虫实战
接下来我们来一次爬虫实战,爬取中网小说网站「笔趣看」上的文字。
(1)实战背景
小说网站-笔趣看:
URL:http://www.biqukan.com/
笔趣看是一个盗版小说网站,这里有很多起点中文网的小说,该网站小说的更新速度稍滞后于起点中文网正版小说的更新速度。并且该网站只支持在线浏览,不支持小说打包下载。因此,本次实战就是从该网站爬取并保存一本名为《一念永恒》的小说,该小说是耳根正在连载中的一部玄幻小说。PS:本实例仅为交流学习,支持耳根大大,请上起点中文网订阅。
(2)小试牛刀
我们先看下《一念永恒》小说的第一章内容,URL:http://www.biqukan.com/1_1094/5403177.html
我们先用已经学到的知识获取 HTML 信息试一试,编写代码如下:
# -*- coding:UTF-8 -*-
import requests
if __name__ == '__main__':
target = 'http://www.biqukan.com/1_1094/5403177.html'
req = requests.get(url=target)
print(req.text)
运行代码,可以看到如下结果:
可以看到,我们很轻松地获取了 HTML 信息。但是,很显然,很多信息是我们不想看到的,我们只想获得如右侧所示的正文内容,我们不关心 div、br 这些 html 标签。如何把正文内容从这些众多的 html 标签中提取出来呢?这就是本次实战的主要内容。
(3)Beautiful Soup
爬虫的第一步,获取整个网页的 HTML 信息,我们已经完成。接下来就是爬虫的第二步,解析 HTML 信息,提取我们感兴趣的内容。 对于本小节的实战,我们感兴趣的内容就是文章的正文。提取的方法有很多,例如使用正则表达式、Xpath、Beautiful Soup 等。对于初学者而言,最容易理解,并且使用简单的方法就是使用 Beautiful Soup 提取感兴趣内容。
Beautiful Soup 的安装方法和 requests 一样,使用如下指令安装(也是二选一):
pip install beautifulsoup4
easy_install beautifulsoup4
一个强大的第三方库,都会有一个详细的官方文档。我们很幸运,Beautiful Soup 也是有中文的官方文档。URL:
http://beautifulsoup.readthedocs.io/zh_CN/latest/
同理,我会根据实战需求,讲解 Beautiful Soup 库的部分使用方法,更详细的内容,请查看官方文档。
现在,我们使用已经掌握的审查元素方法,查看一下我们的目标页面,你会看到如下内容:
不难发现,文章的所有内容都放在了一个名为 div 的“东西下面”,这个"东西"就是 html 标签。HTML 标签是 HTML 语言中最基本的单位,HTML 标签是 HTML 最重要的组成部分。不理解,没关系,我们再举个简单的例子:
一个女人的包包里,会有很多东西,她们会根据自己的习惯将自己的东西进行分类放好。镜子和口红这些会经常用到的东西,会归放到容易拿到的外侧口袋里。那些不经常用到,需要注意安全存放的证件会放到不容易拿到的里侧口袋里。
html 标签就像一个个“口袋”,每个“口袋”都有自己的特定功能,负责存放不同的内容。显然,上述例子中的 div 标签下存放了我们关心的正文内容。这个 div 标签是这样的:
细心的朋友可能已经发现,除了 div 字样外,还有 id 和 class。id 和 class 就是 div 标签的属性,content 和 showtxt 是属性值,一个属性对应一个属性值。这东西有什么用?它是用来区分不同的 div 标签的,因为 div 标签可以有很多,我们怎么加以区分不同的 div 标签呢?就是通过不同的属性值。
仔细观察目标网站一番,我们会发现这样一个事实:class 属性为 showtxt 的 div 标签,独一份!这个标签里面存放的内容,是我们关心的正文部分。
知道这个信息,我们就可以使用 Beautiful Soup 提取我们想要的内容了,编写代码如下:
# -*- coding:UTF-8 -*-
from bs4 import BeautifulSoup
import requests
if __name__ == "__main__":
target = 'http://www.biqukan.com/1_1094/5403177.html'
req = requests.get(url = target)
html = req.text
bf = BeautifulSoup(html)
texts = bf.find_all('div', class_ = 'showtxt')
print(texts)
在解析 html 之前,我们需要创建一个 Beautiful Soup 对象。BeautifulSoup 函数里的参数就是我们已经获得的 html 信息。然后我们使用find_all
方法,获得 html 信息中所有 class 属性为 showtxt 的 div 标签。find_all
方法的第一个参数是获取的标签名,第二个参数class_
是标签的属性,为什么不是 class,而带了一个下划线呢?因为 python 中 class 是关键字,为了防止冲突,这里使用class_
表示标签的 class 属性,class_
后面跟着的 showtxt 就是属性值了。看下我们要匹配的标签格式:
这样对应的看一下,是不是就懂了?可能有人会问了,为什么不是find_all('div', id = 'content', class_ = 'showtxt')
?这样其实也是可以的,属性是作为查询时候的约束条件,添加一个class_='showtxt'
条件,我们就已经能够准确匹配到我们想要的标签了,所以我们就不必再添加 id 这个属性了。运行代码查看我们匹配的结果:
我们可以看到,我们已经顺利匹配到我们关心的正文内容,但是还有一些我们不想要的东西。比如 div 标签名,br 标签,以及各种空格。怎么去除这些东西呢?我们继续编写代码:
# -*- coding:UTF-8 -*-
from bs4 import BeautifulSoup
import requests
if __name__ == "__main__":
target = 'http://www.biqukan.com/1_1094/5403177.html'
req = requests.get(url = target)
html = req.text
bf = BeautifulSoup(html)
texts = bf.find_all('div', class_ = 'showtxt')
print(texts[0].text.replace('\xa0'*8,'\n\n'))
find_all 匹配的返回的结果是一个列表。提取匹配结果后,使用 text 属性,提取文本内容,滤除 br 标签。随后使用 replace 方法,剔除空格,替换为回车进行分段。
在 html 中是用来表示空格的。replace('\xa0'*8,'\n\n')
就是去掉下图的八个空格符号,并用回车代替:
程序运行结果如下:
可以看到,我们很自然的匹配到了所有正文内容,并进行了分段。我们已经顺利获得了一个章节的内容,要想下载正本小说,我们就要获取每个章节的链接。我们先分析下小说目录:
URL:http://www.biqukan.com/1_1094/
通过审查元素,我们发现可以发现,这些章节都存放在了 class 属性为 listmain 的 div 标签下,选取部分 html 代码如下:
在分析之前,让我们先介绍一个概念:父节点、子节点、孙节点。和
限定了标签的开始和结束的位置,他们是成对出现的,有开始位置,就有结束位置。我们可以看到,在
标签包含
标签,那这个
标签就是
标签的子节点,
标签又包含
标签和
标签,那么
标签和
标签就是
标签的孙节点。有点绕?那你记住这句话:
谁包含谁,谁就是谁儿子!
他们之间的关系都是相对的 。比如对于
标签,它的子节点是
标签,它的父节点是
标签。这跟我们人是一样的,上有老下有小。
看到这里可能有人会问,这有好多
标签和
标签啊!不同的
标签,它们是什么关系啊?显然,兄弟姐妹喽!我们称它们为兄弟结点。
好了,概念明确清楚,接下来,让我们分析一下问题。我们看到每个章节的名字存放在了
标签里面。
标签还有一个 href 属性。这里就不得不提一下
标签的定义了,
标签定义了一个超链接,用于从一张页面链接到另一张页面。
标签最重要的属性是 href 属性,它指示链接的目标。
我们将之前获得的第一章节的 URL 和
标签对比看一下:
http://www.biqukan.com/1_1094/5403177.html
不难发现,
标签中 href 属性存放的属性值/1_1094/5403177.html
是章节 URLhttp://www.biqukan.com/1_1094/5403177.html
的后半部分。其他章节也是如此!那这样,我们就可以根据
标签的 href 属性值获得每个章节的链接和名称了。
总结一下:小说每章的链接放在了 class 属性为 listmain 的标签下的
标签中。链接具体位置放在 html->body->div->dl->dd->a 的 href 属性中。先匹配 class 属性为 listmain 的
标签,再匹配
标签。编写代码如下:
# -*- coding:UTF-8 -*-
from bs4 import BeautifulSoup
import requests
if __name__ == "__main__":
target = 'http://www.biqukan.com/1_1094/'
req = requests.get(url = target)
html = req.text
div_bf = BeautifulSoup(html)
div = div_bf.find_all('div', class_ = 'listmain')
print(div[0])
还是使用 find_all 方法,运行结果如下:
很顺利,接下来再匹配每一个
标签,并提取章节名和章节文章。如果我们使用 Beautiful Soup 匹配到了下面这个
标签,如何提取它的 href 属性和
标签里存放的章节名呢?
第一章 他叫白小纯
方法很简单,对 Beautiful Soup 返回的匹配结果 a,使用 a.get('href')方法就能获取 href 的属性值,使用 a.string 就能获取章节名,编写代码如下:
# -*- coding:UTF-8 -*-
from bs4 import BeautifulSoup
import requests
if __name__ == "__main__":
server = 'http://www.biqukan.com/'
target = 'http://www.biqukan.com/1_1094/'
req = requests.get(url = target) html = req.text
div_bf = BeautifulSoup(html)
div = div_bf.find_all('div', class_ = 'listmain')
a_bf = BeautifulSoup(str(div[0]))
a = a_bf.find_all('a')
for each in a:
print(each.string, server + each.get('href'))
因为 find_all 返回的是一个列表,里边存放了很多的
标签,所以使用 for 循环遍历每个
标签并打印出来,运行结果如下。
最上面匹配的一千多章的内容是最新更新的 12 章节的链接。这 12 章内容会和下面的重复,所以我们要滤除,除此之外,还有那 3 个外传,我们也不想要。这些都简单地剔除就好。
(3)整合代码
每个章节的链接、章节名、章节内容都有了。接下来就是整合代码,将获得内容写入文本文件存储就好了。编写代码如下:
# -*- coding:UTF-8 -*-
from bs4 import BeautifulSoup
import requests, sys
class downloader(object):
def __init__(self):
self.server = 'http://www.biqukan.com/'
self.target = 'http://www.biqukan.com/1_1094/'
self.names = [] #存放章节名
self.urls = [] #存放章节链接
self.nums = 0 #章节数
def get_download_url(self):
req = requests.get(url = self.target)
html = req.text
div_bf = BeautifulSoup(html)
div = div_bf.find_all('div', class_ = 'listmain')
a_bf = BeautifulSoup(str(div[0]))
a = a_bf.find_all('a')
self.nums = len(a[15:]) #剔除不必要的章节,并统计章节数
for each in a[15:]:
self.names.append(each.string)
self.urls.append(self.server + each.get('href'))
"""
函数说明:获取章节内容
Parameters:
target - 下载连接(string)
Returns:
texts - 章节内容(string)
"""
def get_contents(self, target):
req = requests.get(url = target)
html = req.text
bf = BeautifulSoup(html)
texts = bf.find_all('div', class_ = 'showtxt')
texts = texts[0].text.replace('\xa0'*8,'\n\n')
return texts
"""
函数说明:将爬取的文章内容写入文件
Parameters:
name - 章节名称(string)
path - 当前路径下,小说保存名称(string)
text - 章节内容(string)
Returns:
无
"""
def writer(self, name, path, text):
write_flag = True
with open(path, 'a', encoding='utf-8') as f:
f.write(name + '\n')
f.writelines(text)
f.write('\n\n')
if __name__ == "__main__":
dl = downloader()
dl.get_download_url()
print('《一年永恒》开始下载:')
for i in range(dl.nums):
dl.writer(dl.names[i], '一念永恒.txt', dl.get_contents(dl.urls[i]))
sys.stdout.write(" 已下载:%.3f%%" % float(i/dl.nums*100) + '\r')
sys.stdout.flush()
print('《一年永恒》下载完成')
很简单的程序,单进程跑,没有开进程池。下载速度略慢,喝杯茶休息休息吧。代码运行效果如下图所示:
以上就是一次文字爬虫实战。
本文完。
本文转自 Jack Cui 的博客文章,公众号见下方:
你可能感兴趣的:(从零介绍怎么写一个爬虫实战)
python 读excel每行替换_Python脚本操作Excel实现批量替换功能
weixin_39646695
python 读excel每行替换
Python脚本操作Excel实现批量替换功能大家好,给大家分享下如何使用Python脚本操作Excel实现批量替换。使用的工具Openpyxl,一个处理excel的python库,处理excel,其实针对的就是WorkBook,Sheet,Cell这三个最根本的元素~明确需求原始excel如下我们的目标是把下面excel工作表的sheet1表页A列的内容“替换我吧”批量替换为B列的“我用来替换的
男士护肤品哪个牌子好?十大男士护肤品排行榜
高省APP珊珊
很多男生意识到护肤的必要性,开始着手护肤,但不知道该选哪个男士护肤品品牌使用好。目前市面上很多男士护肤品品牌,可谓琳琅满目,让人眼花缭乱。男士挑选护肤品时,根据自己皮肤需求去正规渠道挑选合适的知名护肤品比较放心靠谱。高省APP,是2021年推出的平台,0投资,0风险、高省APP佣金更高,模式更好,终端用户不流失。【高省】是一个自用省钱佣金高,分享推广赚钱多的平台,百度有几百万篇报道,也期待你的加入
三菱PLC全套学习资料及应用手册
good2know
本文还有配套的精品资源,点击获取简介:三菱PLC作为工业自动化领域的核心设备,其系列产品的学习和应用需要全面深入的知识。本次资料包为学习者提供从基础到进阶的全方位学习资源,包括各种型号PLC的操作手册、编程指南、软件操作教程以及实际案例分析,旨在帮助用户系统掌握PLC的编程语言、指令系统及在各类工业应用中的实施。1.三菱PLC基础知识入门1.1PLC的基本概念可编程逻辑控制器(PLC)是工业自动化
《玉骨遥》:大司命为什么不杀朱颜?原因没那么简单
windy天意晚晴
《玉骨遥》里,朱颜就是时影的命劫之人。重明与时影早就知道,他们一直瞒着大司命,如今大司命也知道了真相。可是大司命却没有杀朱颜,而是给朱颜下了诛心咒,还说时影的命劫已经破了,真的如此吗?1、计划总是赶不上变化的大司命从目前剧情来说,大司命还不如时影,他信心十足的事情总会有纰漏。他不让时影见命劫之女,结果时影还是遇上了。他想让时影走火入魔,一心复仇,结果时影在朱颜的劝说下放下了仇恨。大司命让时影开山收
日更006 终极训练营day3
懒cici
人生创业课(2)今天的主题:学习方法一:遇到有用的书,反复读,然后结合自身实际,列践行清单,不要再写读书笔记思考这本书与我有什么关系,我在哪些地方能用到,之后我该怎么用方法二:读完书没映像怎么办?训练你的大脑,方法:每读完一遍书,立马合上书,做一场分享,几分钟都行对自己的学习要求太低,要逼自己方法三:学习深度不够怎么办?找到细分领域的榜样,把他们的文章、书籍、产品都体验一遍,成为他们的超级用户,向
自律打卡第四天:比昨天进步一点点
花儿的念想
今天新闻我们县城又确诊了一例,截止目前已经确诊的三例了,打开,看了一篇简友写的武汉的真实情况,有病住不了院,还没等到床位已经去世的消息,心里更加的难受,武汉尚且这样,如果是我们这没有高速没有火车的十八线的小县城发生这种情况,那情况将是更加的不堪设想,不敢想,唯有祈求灾难早点快去,平安才是最大的福气。突然觉得我的自律打卡,比昨天进步一点点。更希望疫情战争每一天都要比昨天好一点,希望一觉醒来听到的是好
9、汇编语言编程入门:从环境搭建到简单程序实现
神经网络酱
汇编语言 MEPIS GNU工具链
汇编语言编程入门:从环境搭建到简单程序实现1.数据存储介质问题解决在处理数据存储时,若要使用MEPIS系统,需确保有其可访问的存储介质。目前,MEPIS无法向采用NTFS格式(常用于Windows2000和XP工作站)的硬盘写入数据。不过,若硬盘采用FAT32格式,MEPIS就能进行写入操作。此外,MEPIS还能将文件写入软盘和大多数USB闪存驱动器。若工作站连接到局域网,还可通过FTP协议或挂载
三件事—小白猫·雨天·八段锦
咸鱼月亮
1.最近楼下出现一只非常漂亮的粘人小白猫,看着不像是流浪猫,非常亲人。眼睛比蓝球的还大,而且是绿色的,很漂亮。第一次遇到它,它就跟我到电梯口,如果我稍微招招手,肯定就跟我进电梯了。后来我喂过它几次,好可惜不能养它,一只蓝球就是我的极限了。2.下雨天就心烦,好奇怪。明明以前我超爱看窗外的雨和听雨声,看来近来的心情不够宁静了。3.最近在练八段锦,从第一次就爱上了这个运动,很轻松缓慢,但是却出汗。感觉可
《极简思维》第三部分
小洋苏兮
整理你的人际关系如何改善人际关系?摘录:因为人际关系问题是人们生活中不快乐的主要原因。感想:感觉这个说的挺对,之前我总是埋头学习,不管舍友不管自己的合作伙伴的一些事情,但实际上,这学期关注了之后好多了摘录:“亲密关系与社交会让你健康而快乐。这是基础。太过于关注成就或不太关心人际关系的人都不怎么快乐。基本上来说,人类就是建立在人脉关系上的。”感想:但是如果有时想的太多就不太好,要以一个开放的心态跟别
力扣热题100-------54. 螺旋矩阵
海航Java之路
力扣 leetcode 矩阵 java
给你一个m行n列的矩阵matrix,请按照顺时针螺旋顺序,返回矩阵中的所有元素。示例1:输入:matrix=[[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]示例2:输入:matrix=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]输出:[1,2,3,4,8,12,11,10,9,5,6,7]提示:m==matrix.lengthn
我不懂什么是爱,但我给你全部我拥有的
香尧
因为怕黑,所以愿意陪伴在夜中行走的人,给他一点点的安全感。因为渴望温柔与爱,所以愿意为别的孩子付出爱与温柔。因为曾遭受侮辱和伤害,所以不以同样的方式施于其他人。如果你向别人出之以利刃,对方还了你爱与包容,真的不要感激他,真的不要赞美他。每一个被人伤害过的人心里都留下了一颗仇恨的种子,他也会想要有一天以眼还眼,以牙还牙。但他未让那颗种子生根发芽,他用一把心剑又一次刺向他自己,用他血荐仇恨,开出一朵温
SpringMVC执行流程(原理),通俗易懂
国服冰
SpringMVC spring mvc
SpringMVC执行流程(原理),通俗易懂一、图解SpringMVC流程二、进一步理解Springmvc的执行流程1、导入依赖2、建立展示的视图3、web.xml4、spring配置文件springmvc-servlet5、Controller6、tomcat配置7、访问的url8、视图页面一、图解SpringMVC流程图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提
C++ 计数排序、归并排序、快速排序
每天搬一点点砖
c++ 数据结构 算法
计数排序:是一种基于哈希的排序算法。他的基本思想是通过统计每个元素的出现次数,然后根据统计结果将元素依次放入排序后的序列中。这种排序算法适用于范围较小的情况,例如整数范围在0到k之间计数排序步骤:1初始化一个长度为最大元素值加1的计数数组,所有元素初始化为02遍历原始数组,将每个元素值作为索引,在计数数组中对应位置加13将数组清空4遍历计数器数组,按照数组中的元素个数放回到元数组中计数排序的优点和
2023-11-02
一帆f
发现浸润心田的感觉:今天一个机缘之下突然想分享我的婆媳关系,我一边分享一边回忆我之前和儿媳妇关系的微妙变化,特别是分享到我能感受到儿媳妇的各种美好,现在也能心平气和的和老公平等对话,看到自己看到老公,以己推人以人推己自然而然的换位思考,心中有一种美好的能量在涌动,一种浸润心田的感觉从心胸向全身扩散,美好极了……我很想记住这种感觉,赶紧把它写下来以留纪念,也就是当我看见他人的美好,美好的美妙的浸润心
贫穷家庭的孩子考上985以后会怎样?
Mellisa蜜思言
我出生在一个贫穷的农村家庭,据我妈说,我出生的时候才4斤多,而她生完我以后月子里就瘦到70斤。家里一直很穷,父母都是在菜市场卖菜的,家里还有几亩地种庄稼的。我很小开始就要去帮忙,暑假的生活就是帮忙去卖菜和割稻谷,那时候自己对于割稻谷这种事情有着莫名的恐惧,生怕自己长大以后还是每年都要过着割稻谷这种日子。父母因为忙于生计无暇顾及我的学习,幸好我因为看到他们这样子的生活,内心里有深深的恐惧感,驱使着我
48. 旋转图像 - 力扣(LeetCode)
Fiee-77
# 数组 leetcode 算法 python 数据结构 数组
题目:给定一个n×n的二维矩阵matrix表示一个图像。请你将图像顺时针旋转90度。你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。示例1:输入:matrix=[[1,2,3],[4,5,6],[7,8,9]]输出:[[7,4,1],[8,5,2],[9,6,3]]示例2:输入:matrix=[[5,1,9,11],[2,4,8,10],[13,3,6,
日更50天有什么收益?
星湾二宝
坚持在平台上日更50天了,平台也为我生成了日更50天徽章,小开心一下这份坚持。日更50天徽章那坚持50天都有哪些收益呢?收益一,就是最直观的那些钻和贝,我这边确实不太高,但是这些贝足够支撑我保持会员的资格,能够在发文的时候帮助友友们去除广告,方便阅读。钻和贝收益二,文章的收获,日更50天,坚持写作3.7万文字,书写的文字也从开始的流水账/碎碎念逐渐加入自己的思考和观点。以前,一个念头会一晃而过,如
别再讲道理啦,对方听不进去的
方所
我之前写过一篇叫做《你总妄想改变他人》,然后就有朋友跟我说,有一些方法可以改变他人之类的。嗯,是这样,但是任何具体的问题,都要限定好语境,描述清楚前提条件,然后再表达观点,我的这位朋友的说法就犯了一刀切的错误,这样并不能让讨论正常展开(这篇我得先给她看看,不然可能会挨揍)。好了,hhhh,谁让她不能写文章呢,我就来再说一说吧。我前面说过,我们在学到一个道理、学会一种方法之后,总是迫不及待地想要去与
Git 与 GitHub 的对比与使用指南
一念&
其它 git github
Git与GitHub的对比与使用指南在软件开发中,Git和GitHub是两个密切相关但本质不同的工具。下面我将逐步解释它们的定义、区别、核心概念以及如何协同使用,确保内容真实可靠,基于广泛的技术实践。1.什么是Git?Git是一个分布式版本控制系统,由LinusTorvalds于2005年创建。它的核心功能是跟踪代码文件的变化,帮助开发者管理项目历史记录、协作和回滚错误。Git是开源的,可以在本地
深入解析JVM工作原理:从字节码到机器指令的全过程
一、JVM概述Java虚拟机(JVM)是Java平台的核心组件,它实现了Java"一次编写,到处运行"的理念。JVM是一个抽象的计算机器,它有自己的指令集和运行时内存管理机制。JVM的主要职责:加载:读取.class文件并验证其正确性存储:管理内存分配和垃圾回收执行:解释或编译字节码为机器指令安全:提供沙箱环境限制恶意代码二、JVM架构详解JVM由三个主要子系统组成:1.类加载子系统类加载过程分为
叮嘱!北恒高级班周一丰创投杯量化私募大赛不正规!受骗不能提现出金被骗真相曝光!
天权顾问
量化北恒私募实盘大赛周一丰投票项目安全吗?量化北恒私募实盘大赛周一丰积分投票已经亏损被骗了怎么办?警惕!量化北恒私募实盘大赛周一丰十选五项目合法吗——杀猪盘骗局!被骗提不了款!提不了现!出不来金!不要上当!自古有句话讲得好“人善被欺、马善被骑”,现如今也是被骗子利用到了极致,人善就真该被欺骗吗?狡猾的骗子们就利用到了这点,利用同情心、爱心去进行诈骗,宣传公益捐款、爱心慈善打比赛来骗取资金!正常的投
Linux系统配置(应用程序)
1风天云月
Linux linux 应用程序 编译安装 rpm http
目录前言一、应用程序概述1、命令与程序的关系2、程序的组成3、软件包封装类型二、RPM1、RPM概述2、RPM用法三、编译安装1、解包2、配置3、编译4、安装5、启用httpd服务结语前言在Linux中的应用程序被视为将软件包安装到系统中后产生的各种文档,其中包括可执行文件、配置文件、用户手册等内容,这些文档被组织为一个有机的整体,为用户提供特定的功能,因此对于“安装软件包”与“安装应用程序”这两
第28章 汇编语言--- 异常处理
hummhumm
汇编 算法 开发语言 程序设计 高级语言 异常处理 汇编语言
在汇编语言中,异常处理是一个重要的概念,它涉及到处理器如何响应和处理程序运行时发生的非正常情况。异常可以是硬件错误(例如除零错误、非法指令)或者软件触发的中断(例如系统调用)。当发生异常时,处理器会暂停当前正在执行的程序,并转移到一个预先定义好的位置来处理这个异常。为了详细阐述第28章关于汇编语言中的异常处理,我们可以考虑一个简化的例子,展示异常处理的基本结构。请注意,实际的代码将取决于具体的处理
【C++算法】76.优先级队列_前 K 个高频单词
流星白龙
优选算法C++ c++ 算法 开发语言
文章目录题目链接:题目描述:解法C++算法代码:题目链接:692.前K个高频单词题目描述:解法利用堆来解决TopK问题预处理一下原始的字符串数组,用一个哈希表统计一下每一个单词出现的频次。创建一个大小为k的堆频次:小根堆字典序(频次相同的时候):大根堆循环让元素依次进堆判断提取结果C++算法代码:classSolution{//定义类型别名,PSI表示对typedefpairPSI;//自定义比较
关于流媒体播放器EasyPlayer和EasyPlayerPro的介绍以及其区别
EasyDarwin
EasyDarwin 音视频 ffmpeg 人工智能 大数据 ar
EasyPlayer是一款流媒体播放器系列项目,它支持多种流媒体协议的播放,包括但不限于RTSP、RTMP、HTTP、HLS、UDP、RTP、File等。除此之外,EasyPlayer还支持本地文件播放和多种功能特性,包括本地抓拍、本地录像、播放旋转、多屏播放、倍数播放等。EasyPlayer核心基于ffmpeg,稳定、高效、可靠、可控。随着多年的不断发展和迭代,EasyPlayer基于成功的实践
Flowable 高级扩展:自定义元素与性能优化实战
练习时长两年半的程序员小胡
Flowable 流程引擎实战指南 流程图 flowable BPMN 流程引擎 java
在前五篇文章中,我们从基础概念、流程设计、API实战、SpringBoot集成,到外部系统协同,逐步构建了Flowable的应用体系。但企业级复杂场景中,原生功能往往难以满足定制化需求——比如需要特殊的审批规则网关、与决策引擎联动实现动态路由,或是在高并发场景下优化流程引擎性能。本文将聚焦Flowable的高级扩展能力,详解如何自定义流程元素、集成规则引擎,并掌握大型系统中的性能调优策略。一、自定
2022-04-07
上善若水1979527
昨天苏阿姨来给我送普门品!和她一块来的还有另外一个阿姨!我下去拿时!那阿姨说你不是干房产的小赵!帮我租房的!我说你认识我?对啊!你帮我租的房子!我没印象了!我和保红一块!我说我想起来了阿姨!你这运动服一换!小电车一骑!一下年轻十岁我早记不得了!我只记得一九年五一带看了河滨美航还有德胜的好多套房子!你都不当意!你告诉我你每晚拜观音菩萨说快让小赵普萨帮我找套合适的房子吧!我把本子上记得半年内的德胜房源
互信息:理论框架、跨学科应用与前沿进展
大千AI助手
人工智能 Python # OTHER 人工智能 深度学习 算法 互信息 香农 通信 随机变量
1.起源与核心定义互信息(MutualInformation,MI)由克劳德·香农(ClaudeShannon)在1948年开创性论文《AMathematicalTheoryofCommunication》中首次提出,该论文奠定了现代信息论的基础。互信息用于量化两个随机变量之间的统计依赖关系,定义为:若已知一个随机变量的取值,能为另一个随机变量提供的信息量。数学上,对于离散随机变量XXX和YYY,
什么是缓存雪崩?缓存击穿?缓存穿透?分别如何解决?什么是缓存预热?
daixin8848
缓存 redis java 开发语言
缓存雪崩:在一个时间段内,有大量的key过期,或者Redis服务宕机,导致大量的请求到达数据库,带来巨大压力-给key设置不同的TTL、利用Redis集群提高服务的高可用性、添加多级缓存、添加降级流策略缓存击穿:给某一个key设置了过期时间,当key过期的时间,恰好这个时间点有大量的并发请求访问这个key,可能会瞬间把数据库压垮-互斥锁:缓存失败时,只允许一个请求去加载数据并更新缓存,其他请求阻塞
高省邀请码哪个级别最高?高省原始高级邀请码500888
凌风导师
高省是杭州长孚科技有限公司开辟的一个项目(高省APP),已获数千万投资,主打外交电商+新零售,提供淘宝好省京东等主流电商途径的大额优惠券(直接在淘宝等途径购买是没有该优惠券的)。用户们可以利用这些软件享受折扣买东西优惠,一起来看看购物省钱app网上买东西省钱的软件有哪些吧!网购省钱软件靠谱吗包围淘宝等途径产品的左右,也便是你可以大概在高省买你的确想买的任何产品,并且享受额定优惠,优惠力度为-(大部
戴尔笔记本win8系统改装win7系统
sophia天雪
win7 戴尔 改装系统 win8
戴尔win8 系统改装win7 系统详述
第一步:使用U盘制作虚拟光驱:
1)下载安装UltraISO:注册码可以在网上搜索。
2)启动UltraISO,点击“文件”—》“打开”按钮,打开已经准备好的ISO镜像文
BeanUtils.copyProperties使用笔记
bylijinnan
java
BeanUtils.copyProperties VS PropertyUtils.copyProperties
两者最大的区别是:
BeanUtils.copyProperties会进行类型转换,而PropertyUtils.copyProperties不会。
既然进行了类型转换,那BeanUtils.copyProperties的速度比不上PropertyUtils.copyProp
MyEclipse中文乱码问题
0624chenhong
MyEclipse
一、设置新建常见文件的默认编码格式,也就是文件保存的格式。
在不对MyEclipse进行设置的时候,默认保存文件的编码,一般跟简体中文操作系统(如windows2000,windowsXP)的编码一致,即GBK。
在简体中文系统下,ANSI 编码代表 GBK编码;在日文操作系统下,ANSI 编码代表 JIS 编码。
Window-->Preferences-->General -
发送邮件
不懂事的小屁孩
send email
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.MultiPartEmail;
动画合集
换个号韩国红果果
html css
动画 指一种样式变为另一种样式 keyframes应当始终定义0 100 过程
1 transition 制作鼠标滑过图片时的放大效果
css
.wrap{
width: 340px;height: 340px;
position: absolute;
top: 30%;
left: 20%;
overflow: hidden;
bor
网络最常见的攻击方式竟然是SQL注入
蓝儿唯美
sql注入
NTT研究表明,尽管SQL注入(SQLi)型攻击记录详尽且为人熟知,但目前网络应用程序仍然是SQLi攻击的重灾区。
信息安全和风险管理公司NTTCom Security发布的《2015全球智能威胁风险报告》表明,目前黑客攻击网络应用程序方式中最流行的,要数SQLi攻击。报告对去年发生的60亿攻击 行为进行分析,指出SQLi攻击是最常见的网络应用程序攻击方式。全球网络应用程序攻击中,SQLi攻击占
java笔记2
a-john
java
类的封装:
1,java中,对象就是一个封装体。封装是把对象的属性和服务结合成一个独立的的单位。并尽可能隐藏对象的内部细节(尤其是私有数据)
2,目的:使对象以外的部分不能随意存取对象的内部数据(如属性),从而使软件错误能够局部化,减少差错和排错的难度。
3,简单来说,“隐藏属性、方法或实现细节的过程”称为——封装。
4,封装的特性:
4.1设置
[Andengine]Error:can't creat bitmap form path “gfx/xxx.xxx”
aijuans
学习Android遇到的错误
最开始遇到这个错误是很早以前了,以前也没注意,只当是一个不理解的bug,因为所有的texture,textureregion都没有问题,但是就是提示错误。
昨天和美工要图片,本来是要背景透明的png格式,可是她却给了我一个jpg的。说明了之后她说没法改,因为没有png这个保存选项。
我就看了一下,和她要了psd的文件,还好我有一点
自己写的一个繁体到简体的转换程序
asialee
java 转换 繁体 filter 简体
今天调研一个任务,基于java的filter实现繁体到简体的转换,于是写了一个demo,给各位博友奉上,欢迎批评指正。
实现的思路是重载request的调取参数的几个方法,然后做下转换。
android意图和意图监听器技术
百合不是茶
android 显示意图 隐式意图 意图监听器
Intent是在activity之间传递数据;Intent的传递分为显示传递和隐式传递
显式意图:调用Intent.setComponent() 或 Intent.setClassName() 或 Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。
隐式意图;不指明调用的名称,根据设
spring3中新增的@value注解
bijian1013
java spring @Value
在spring 3.0中,可以通过使用@value,对一些如xxx.properties文件中的文件,进行键值对的注入,例子如下:
1.首先在applicationContext.xml中加入:
<beans xmlns="http://www.springframework.
Jboss启用CXF日志
sunjing
log jboss CXF
1. 在standalone.xml配置文件中添加system-properties:
<system-properties> <property name="org.apache.cxf.logging.enabled" value=&
【Hadoop三】Centos7_x86_64部署Hadoop集群之编译Hadoop源代码
bit1129
centos
编译必需的软件
Firebugs3.0.0
Maven3.2.3
Ant
JDK1.7.0_67
protobuf-2.5.0
Hadoop 2.5.2源码包
Firebugs3.0.0
http://sourceforge.jp/projects/sfnet_findbug
struts2验证框架的使用和扩展
白糖_
框架 xml bean struts 正则表达式
struts2能够对前台提交的表单数据进行输入有效性校验,通常有两种方式:
1、在Action类中通过validatexx方法验证,这种方式很简单,在此不再赘述;
2、通过编写xx-validation.xml文件执行表单验证,当用户提交表单请求后,struts会优先执行xml文件,如果校验不通过是不会让请求访问指定action的。
本文介绍一下struts2通过xml文件进行校验的方法并说
记录-感悟
braveCS
感悟
再翻翻以前写的感悟,有时会发现自己很幼稚,也会让自己找回初心。
2015-1-11 1. 能在工作之余学习感兴趣的东西已经很幸福了;
2. 要改变自己,不能这样一直在原来区域,要突破安全区舒适区,才能提高自己,往好的方面发展;
3. 多反省多思考;要会用工具,而不是变成工具的奴隶;
4. 一天内集中一个定长时间段看最新资讯和偏流式博
编程之美-数组中最长递增子序列
bylijinnan
编程之美
import java.util.Arrays;
import java.util.Random;
public class LongestAccendingSubSequence {
/**
* 编程之美 数组中最长递增子序列
* 书上的解法容易理解
* 另一方法书上没有提到的是,可以将数组排序(由小到大)得到新的数组,
* 然后求排序后的数组与原数
读书笔记5
chengxuyuancsdn
重复提交 struts2的token验证
1、重复提交
2、struts2的token验证
3、用response返回xml时的注意
1、重复提交
(1)应用场景
(1-1)点击提交按钮两次。
(1-2)使用浏览器后退按钮重复之前的操作,导致重复提交表单。
(1-3)刷新页面
(1-4)使用浏览器历史记录重复提交表单。
(1-5)浏览器重复的 HTTP 请求。
(2)解决方法
(2-1)禁掉提交按钮
(2-2)
[时空与探索]全球联合进行第二次费城实验的可能性
comsci
二次世界大战前后,由爱因斯坦参加的一次在海军舰艇上进行的物理学实验 -费城实验
至今给我们大家留下很多迷团.....
关于费城实验的详细过程,大家可以在网络上搜索一下,我这里就不详细描述了
在这里,我的意思是,现在
easy connect 之 ORA-12154: TNS: 无法解析指定的连接标识符
daizj
oracle ORA-12154
用easy connect连接出现“tns无法解析指定的连接标示符”的错误,如下:
C:\Users\Administrator>sqlplus username/
[email protected] :1521/orcl
SQL*Plus: Release 10.2.0.1.0 – Production on 星期一 5月 21 18:16:20 2012
Copyright (c) 198
简单排序:归并排序
dieslrae
归并排序
public void mergeSort(int[] array){
int temp = array.length/2;
if(temp == 0){
return;
}
int[] a = new int[temp];
int
C语言中字符串的\0和空格
dcj3sjt126com
c
\0 为字符串结束符,比如说:
abcd (空格)cdefg;
存入数组时,空格作为一个字符占有一个字节的空间,我们
解决Composer国内速度慢的办法
dcj3sjt126com
Composer
用法:
有两种方式启用本镜像服务:
1 将以下配置信息添加到 Composer 的配置文件 config.json 中(系统全局配置)。见“例1”
2 将以下配置信息添加到你的项目的 composer.json 文件中(针对单个项目配置)。见“例2”
为了避免安装包的时候都要执行两次查询,切记要添加禁用 packagist 的设置,如下 1 2 3 4 5
高效可伸缩的结果缓存
shuizhaosi888
高效可伸缩的结果缓存
/**
* 要执行的算法,返回结果v
*/
public interface Computable<A, V> {
public V comput(final A arg);
}
/**
* 用于缓存数据
*/
public class Memoizer<A, V> implements Computable<A,
三点定位的算法
haoningabc
c 算法
三点定位,
已知a,b,c三个顶点的x,y坐标
和三个点都z坐标的距离,la,lb,lc
求z点的坐标
原理就是围绕a,b,c 三个点画圆,三个圆焦点的部分就是所求
但是,由于三个点的距离可能不准,不一定会有结果,
所以是三个圆环的焦点,环的宽度开始为0,没有取到则加1
运行
gcc -lm test.c
test.c代码如下
#include "stdi
epoll使用详解
jimmee
c linux 服务端编程 epoll
epoll - I/O event notification facility在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。并且,在linu
Hibernate对Enum的映射的基本使用方法
linzx0212
enum Hibernate
枚举
/**
* 性别枚举
*/
public enum Gender {
MALE(0), FEMALE(1), OTHER(2);
private Gender(int i) {
this.i = i;
}
private int i;
public int getI
第10章 高级事件(下)
onestopweb
事件
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/
孙子兵法
roadrunners
孙子 兵法
始计第一
孙子曰:
兵者,国之大事,死生之地,存亡之道,不可不察也。
故经之以五事,校之以计,而索其情:一曰道,二曰天,三曰地,四曰将,五
曰法。道者,令民于上同意,可与之死,可与之生,而不危也;天者,阴阳、寒暑
、时制也;地者,远近、险易、广狭、死生也;将者,智、信、仁、勇、严也;法
者,曲制、官道、主用也。凡此五者,将莫不闻,知之者胜,不知之者不胜。故校
之以计,而索其情,曰
MySQL双向复制
tomcat_oracle
mysql
本文包括:
主机配置
从机配置
建立主-从复制
建立双向复制
背景
按照以下简单的步骤:
参考一下:
在机器A配置主机(192.168.1.30)
在机器B配置从机(192.168.1.29)
我们可以使用下面的步骤来实现这一点
步骤1:机器A设置主机
在主机中打开配置文件 ,
zoj 3822 Domination(dp)
阿尔萨斯
Mina
题目链接:zoj 3822 Domination
题目大意:给定一个N∗M的棋盘,每次任选一个位置放置一枚棋子,直到每行每列上都至少有一枚棋子,问放置棋子个数的期望。
解题思路:大白书上概率那一张有一道类似的题目,但是因为时间比较久了,还是稍微想了一下。dp[i][j][k]表示i行j列上均有至少一枚棋子,并且消耗k步的概率(k≤i∗j),因为放置在i+1~n上等价与放在i+1行上,同理