文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)

1、实例化采集类后,自带一些header信息,类似user-agent、accept之类的,能不手动添加就不手动添加(已实现)

2、在执行了采集后,获取采集到的响应头,解析其中的数据,该记录的记录该执行的执行,在下次调用采集方法时继承获取到的信息(已实现)

3、可以采集纯文本内容,也可以采集二进制流,方便采集页面和下载相关文档(已实现)

4、支持不同的字符编码,响应编码,比如gbk、utf8等,比如gzip、deflate等(已实现)

5、支持不同的请求方法,比如get、put、post、delete、head等(已实现)

6、不管是否采集异常,都能返回状态码(已实现)

7、可以伪造、添加各种头信息,伪造、添加cookie之类的信息,类似 Oauth:xxxx,Signture:xxx等

8、支持301、302之类的自动跳转采集,支持meta自动跳转采集

9、自动完成网址补全,不需要我们在根据采集目标,提取到链接后自己再计算

10、如果可以,尽量支持异步采集

11、如果可以,尽量支持事件委托

12、如果可以,尽量支持proxy

13、如果可以,尽量支持断点续传下载和上传

前一片文章我们建立了一个自定义的爬虫类,已经实现了部分需求了,本文将继续实现剩余的需求。在继续修改我们的类之前,先谈谈spyder。

-----------------------------

为什么要先聊聊spyder呢,主要是因为,老顾找不到一个完整的python包的使用手册,资料都是太零碎的东西,整理起来很麻烦,没有像php手册,或者msdn命名空间介绍一样的东西。就像之前几篇文章一样,每次想做的什么,都要先百度半天,结果本系列文章极度难产。那么spyder有什么好聊的呢?我们来看看。。。

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第1张图片

打开spyder,如界面所示,他分成了几个不同的区域,通常,我们都在左边输入py代码,右下可以看输出结果,右上。。。没好好利用起来啊

比如左侧,我们输入一段代码

[n for n in range(1,100)]

选中并执行这段代码(F9),右下控制台就可以出现反馈信息

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第2张图片

这是一个很方便的调试方法了,当代码中存在交互指令,例如input的时候,右下控制台可以进行交互操作,录入一些信息,这个就不多说了,大家都会用

然后,来想办法利用上右上区域,来辅助我们的学习和工作

在代码区域输入代码

import requests
req = requests()

然后将鼠标指向 requests()这个方法,界面发生变动了

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第3张图片

当我们在浮动的这个提示上点一下后,右上区域就发生了内容改变,Help页里出现了好多信息

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第4张图片

嗯。。。这就很方便了,可以查看方法的具体使用方式了,可惜的是,他并没有像vs里一样,将类的方法全部列出,只能靠类.,然后等待spyder响应后,出现可以使用的属性或方法,然后去选择我们可能需要的内容

现在,我们把指令修改下

import requests
req = requests.Request(url='https://www.baidu.com',method='GET')

运行这些代码,将右上的区域切换到变量资源管理器里(Variable Explorer)

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第5张图片

我们在左侧运行的代码所产生的变量,都会在这里列出,只要没有清除,关闭,一直就保留在这里了,比如刚才的req,我们就可以看到的他描述,用鼠标双击这个变量看看

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第6张图片

这个就是一个比较完整的实例属性和方法了,他里面将这个实例所有可用的方法和属性列出,并可展开查看,这样,就能避免之前我们找不到方法的问题了,直接给一个变量赋值成该类,然后到这边查看,是不是可以代替了vs里的对象浏览器了。

嗯,就简单的说两句spyder,毕竟老顾学python完全是自己摸索,而且岁数大了,看其他视频感觉很不适应,所以就慢慢来吧。至于其他的python 相关的IDE有没有提供这样的查阅方式,老顾也不了解,刚转行的同学们可以自行摸索。然后,我们回归主题,继续搞我们的爬虫类。

------------------------------------------------

7、可以伪造、添加各种头信息,伪造、添加cookie之类的信息,类似 Oauth:xxxx,Signture:xxx等

一般来说,同一个站点很少有需要频繁改动头信息,cookie信息的地方,反爬的网站咱们另说,等进入采集实战的时候再进行应对,咱先说普通的网站。所以,实例化一次,并设置好这些信息,基本上这个实例就可以进行整站采集了,线程问题以后再说。

那么,我们这次把目光瞄准到天眼查这个站,试着根据他的响应,来调整我们的代码,使之能伪造cookie,接收header

先来次没调整前的采集

from spider import Ajax

ajax = Ajax()
html = ajax.Http('https://www.tianyancha.com',Ajax.Method.GET)
print(ajax.status,html)

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第7张图片

很好,可以正常采集天眼查首页,但我们知道,天眼查会返回一些cookie信息,我们现在并没有接收,所以,进行下查找,看看cookie到底存放在哪里

因为对各种包都不熟悉,所以先在爬虫类里面添加两个属性

	@property
	def ResposeHeader(self):
		return self.__headers
	
	@property
	def Session(self):
		return self.__session

一个是用来返回响应头信息的,一个是用来返回会话信息的,让我们看看

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第8张图片

好家伙。。。响应头居然有这么多数据么?548个?哦,展开一看,没那么多,548字节啊,吓我一大跳。

把响应头信息粘贴出来,整理一下看看

{
'Date': 'Wed, 30 Jun 2021 02:25:43 GMT', 
'Content-Type': 'text/html; charset=utf-8', 
'Transfer-Encoding': 'chunked', 
'Connection': 'keep-alive', 
'Set-Cookie': 'aliyungf_tc=8e44b1cb0fc5f37d29864918aa197ec6ed802b989655bf8732efdcd291861558; Path=/; HttpOnly, acw_tc=76b20f8c16250199433016427e4b75bd21ba7840934a083d22e010ebf1aedd;path=/;HttpOnly;Max-Age=1800, csrfToken=s4i4TN-WIKaLgWAXW3qHwbK5; path=/; secure, TYCID=784de430d94a11eb8216f7b2b73bb5b3; path=/; expires=Fri, 30 Jun 2023 02:25:43 GMT; domain=.tianyancha.com', 
'Content-Encoding': 'gzip'
}

哦吼,发现第一个关键信息,Set-Cookie,这个就是服务器发给浏览器的cookie信息了,Set-Cookie是其中的一种方式,记下,一会处理

然后,再看看会话里都有什么

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第9张图片

很显然,会话里也保持了cookies的信息,里面有4个cookie了

print(ajax.Session.cookies)

, , , ]>

得到了一个不知道什么对象的列表,先不管,总之,这里也有cookies,所以,现在我们需要自己定义一个cookies变量,存储这些信息,并在下次采集时继承进来,嗯,也得支持从外边添加cookie。另外,老顾注意到了这个cookie里的domain问题,伪造cookie,domain信息也很重要哦,参考老顾的另一个文章https://blog.csdn.net/superwfei/article/details/9198283?spm=1001.2014.3001.5502,部分网站对cookie验证时,会更严格一些,对不再特定domian的cookie是不予承认的,期待python的cookie处理。。。。

在__init__里,追加一个属性

self.cookies = requests.utils.cookiejar_from_dict({})

然后,我们就可以通过实例添加cookie了

import re
from spider import Ajax

ajax = Ajax()
# 为了获取初始cookie,先访问下天眼查首页
ajax.Http('https://www.tianyancha.com')
ajax.cookies.set('tyc-user-info', '{***********}', domain='.tianyancha.com')
ajax.cookies.set('auth_token', '****************', domain='.tianyancha.com')
html = ajax.Http('https://www.tianyancha.com/company/2968548568',Ajax.Method.GET)
# 显示现在已有cookies
print(ajax.cookies)
print(re.findall(r'
[\s\S]*?(?=
)',html,re.I))

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第10张图片

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第11张图片

很好,cookie伪造成功了,对于域名带前缀点的问题直接就不是问题,证据就是,他没提示登录,其次,电话号码没有星号隐藏。

在这段代码中,我们使用了两次Http方法,第一次是获取初始cookie,如果没有初始cookie,那么我们就需要通过cookies.set方法,自己添加初始cookie,老顾懒得添加,让他自动获取好了,然后第二次采集前,我们追加了两个cookie,并继承了第一次采集的cookie,所以,正确得到了我们的期望结果,而cookie在同一实例内,只需要添加一次,我们这个ajax实例再次使用Http访问天眼查其他企业信息时,就不需要再关注cookie信息了。

剩下的就是伪造请求头了,之前,我们的Header定义,是一个固定的词典,现在要对他进行改装一下,变成动态的词典,同样,在__init__里追加两个赋值

		self.__requestHeaders = {}
		self.__refreshRequestHeaders()

调整Header属性的实现

	@property
	def Header(self):
		return self.__requestHeaders

然后,增加一个私有方法,用来初始化请求头信息

	def __refreshRequestHeaders(self):
		self.__requestHeaders.update({'refer':self.refer
			,'user-agent':self.agent
			,'accept':self.accept
			,'accept-encoding':self.encoding
			,'accept-language':self.lang
			,'cache-control':self.cache})

最后,我们给Ajax类增加一个公开的方法,AddHeader,用来将信息添加到请求头中

	def AddHeader(self,key:str = None,val:str = None,dic:dict = None):
		if dic != None and isinstance(dic,dict):
			self.__requestHeaders.update(dic)
		if key != None and val != None:
			self.__requestHeaders.update({key:val})
from spider import Ajax

ajax = Ajax()
ajax.AddHeader(dic={'oauth':'userinfo'})
ajax.AddHeader('pwd','***')
print(ajax.Header)

运行一下,看看结果

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第12张图片

很好,请求头信息已更新了,虽然有时候需要删除一些请求头,我这里就不去实现了,大家有需求的话,自行实现就可以了,那么第七个需求也告一段落了,下边开始处理跳转问题。

8、支持301、302之类的自动跳转采集,支持meta自动跳转采集

让我们找一个带跳转的网址,比如:http://m6z.cn/6uVNKg,一个用短链接生成器生成的地址

来,我们尝试下,这个请求会发生什么

from spider import Ajax
ajax = Ajax()
html = ajax.Http('http://m6z.cn/6uVNKg')
print(ajax.status,ajax.ResposeHeader)
print(html)

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第13张图片

他自动跳过去了!返回的状态码也是200!中间301、302的过程省略掉了!https://blog.csdn.net/qq_36145663/article/details/101703090,原来,你不想自动301、302,还得设置这个参数allow_redirects=False,算了,让他自动跳吧,不过,我们还是加一个开关,可以用来关闭这个自动跳转,在__init__里追加一个属性

self.redirect = True

在发送请求位置修改 send 参数

res = self.__session.send(request=pre,allow_redirects=self.redirect)

然后就可以成功的禁止自动301,302了

然后,自动跳转,还需要支持meta的跳转,这个稍后再说吧,因为不管是meta跳转,还是js跳转,都涉及到一个网址补全的问题,咱们先解决了这个,再回来支持meta跳转和js跳转

9、自动完成网址补全,不需要我们在根据采集目标,提取到链接后自己再计算

在日常采集过程中,我们经常会碰到页面内链接地址缺少域名,有的则是有域名但没有协议。。。还有其他各种不应该出现的协议。。。。HMMMMMMM,反正经历的多了,自然就知道

这次,我们用政采网ccgp.gov.cn的首页来实验一下

from spider import Ajax
ajax = Ajax()
#html = ajax.Http('http://news.baidu.com/ns?word=school&ie=gb2312&cl=2&rn=20&ct=0&tn=newsrss&class=0')
html = ajax.Http('http://www.ccgp.gov.cn/')
print(html)

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第14张图片

可以看到,页面内N多的链接都是没有网址的,所以,我们需要在采集的时候就处理掉,得到的完整的链接地址,方便我们后续处理。这个时候,该正则大显身手了。对了,在做这个补全之前,我们看看scrapy有没有补全,好像用scrapy的人很多。

行吧,咱也来次最简单的 scrapy 采集,不管那么多,只采集各首页看看

先在命令行运行几个指令

d:\>pip install scrapy

d:\>scrapy startproject ccgp

d:\>cd ccgp

d:\ccgp>scrapy genspider ccgp_gather www.ccgp.gov.cn

的确是很简单就建立了一个针对 ccgp 的采集

然后修改其中一些文件

找到 settings.py,修改 robotstxt_obey,不验证robots.txt

找到 middlewares.py,修改 process_request 方法,在这里追加上 user-agent 信息

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第15张图片

找到 ccgp_gather.py,修改 parse 方法,保存我们采集到的首页内容

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第16张图片

然后回到命令行,运行采集

d:\ccgp>scrapy crawl ccgp_gather

很好,这个页面被采集下来了,我们来瞅瞅看

文盲的Python入门日记:第二十八天,封装一个自定义爬虫类,用来执行日常的采集(二)_第17张图片

得嘞,他也没有进行url补全,顺带一说,感觉用 scrapy 做采集相对来说更麻烦了一点,我以前已经建立了n多的xml,针对自己的采集规则有完整的内容了,什么翻页采集,什么时间范围内采集,什么标题过滤,我们做采集,很少有整站采集,也很少有无脑采集,所以这个scrapy如果要实现以上这些需求,感觉还是挺麻烦的,每个站点都这么搞一次。。。我不如把所有站点信息放到一个xml里,用统一的规则,使用自己的爬虫解析器来一次采集多个站点。总而言之,scrapy和老顾是有缘无分了。但是,如果使用scrapy也并不影响阅读本文哦,大家可不要放弃继续阅读哦。

回到我们自己的url补全上来,再在 Ajax 类里追加一个私有方法 __url_complemented,在 http方法,return html 前,用这个方法修正一下再返回

嗯。。。。。分析下,哪些地方是url?同学们自己列举下哦

有 href ,很常见的,a标签,link 标签

有 src ,也很常见的,script标签,img标签,embed等

还有一些容易被忽略的,url,存在于style中,样式文件中,meta中。。。。

以及更不容易发现的,location,open,存在于 js 之中。。。。action,存在于 form 标签

好了好了,越说越复杂了。。。我这里仅仅先实现前两个啊,再加一个meta,其他的我不考虑哦

做url补全其实也很简单,用正则把 url 提取出来,验证 url 是否是合法的 url,当然特例要排除,什么 about:blank 啦,什么 file:/// 这种本地文件啦,什么 base64 数据(图片src可能会有这个情况)啦。。。总之,只对需要进行补全的 url 进行计算,人本身已经是带协议的就不再操作了

哪些需要补全呢?

1、没有带协议的,比如 //blog.csdn.net,鬼知道他是 http还是https。。。其实这个是由当前页面协议决定的,你在 http域名页面点这个链接,这个结果就是 http://blog.csdn.net,你在https域名页面点开这个链接,结果就是 https://blog.csdn.net

2、链接地址路径不全的,比如 /superwfei,需要补全上域名,得到 blog.csdn.net/superwfei。这种情况相对来说比较复杂,有可能会碰到需要路径计算的时候,比如 ../../../image/xxx.shtml,也有可能碰到不太规范的路径 ..../image/xxx.shtml

老顾碰到的基本就这两种情况,如果有其它情况的,可以告知老顾,再继续研究研究

下面是实现代码 

	def __url_complemented(self,html):
		html = re.sub('''(url|src|href)\\s*=\\s*(['"]?)([^'"]*)(\\2|[\\s\\r\\n\\t])''',self.__url_replace,html,count=0,flags=re.I)
		return html

	def __url_replace(self,m):
		url = m.group(3).strip()
		# about:setting、about:blank 类型的,javascript:void(0) 类型的,#类型的,原样返回
		if re.search('^(#.*|javascript:.*|[a-z_-]+:[a-z_-]+)$',url,re.I):
			return m.string[m.span()[0]:m.span()[1]]
		# 带有协议的,原样返回,例如 https://、ftp://、file://、tencent://等
		if re.search('^[a-z]+://',url,re.I):
			return m.string[m.span()[0]:m.span()[1]]
		# base64 格式,原样返回
		if re.search('^base64',url,re.I):
			return m.string[m.span()[0]:m.span()[1]]
		root = re.sub(r'^([a-z]+:/{2,}[^/]+).*','\\1/',self.current_url.strip(),re.I)
		if re.search('^/(?!/)',url,re.I):
			url = re.sub('^/',root,url,re.I)
		elif re.search('^//',url):
			url = re.sub('^([a-z]+:)//.*$','\\1',root,re.I) + url
		else:
			path = re.sub('/[^/]*$','',self.current_url) + '/'
			p = re.search(r'^[\./]+',url,re.I)
			if p:
				# 具有 ./ 计算路径
				# 获取开头的全部计算路径
				p = p.string[p.span()[0]:p.span()[1]]
				# 去掉路径中 ./ 后,剩余的点的数量,就是路径向上路径的层级
				p = re.sub(r'\./','',p)
				# 获得剩余点的数量,得到层级
				p = len(p)
				pth = path
				for i in range(p):
					pth = re.sub('[^/]+/','',pth,re.I)
				if len(pth)
                    
                    
  • Python 脚本最佳实践2025版
    前文可以直接把这篇文章喂给AI,可以放到AI角色设定里,也可以直接作为提示词.这样,你只管提需求,写脚本就让AI来.概述追求简洁和清晰:脚本应简单明了。使用函数(functions)、常量(constants)和适当的导入(import)实践来有逻辑地组织你的Python脚本。使用枚举(enumerations)和数据类(dataclasses)等数据结构高效管理脚本状态。通过命令行参数增强交互性
  • (Python基础篇)了解和使用分支结构 EternityArt 基础篇python
    目录一、引言二、Python分支结构的类型与语法(一)if语句(单分支)(二)if-else语句(双分支)(三)if-elif-else语句(多分支)三、分支结构的应用场景(一)提示用户输入用户名,然后再提示输入密码,如果用户名是“admin”并且密码是“88888”则提示正确,否则,如果用户名不是admin还提示用户用户名不存在,(二)提示用户输入用户名,然后再提示输入密码,如果用户名是“adm
  • (Python基础篇)循环结构 EternityArt 基础篇python
    一、什么是Python循环结构?循环结构是编程中重复执行代码块的机制。在Python中,循环允许你:1.迭代处理数据:遍历列表、字典、文件内容等。2.自动化重复任务:如批量处理数据、生成序列等。3.控制执行流程:根据条件决定是否继续或终止循环。二、为什么需要循环结构?假设你需要打印1到100的所有偶数:没有循环:需手动编写100行print()语句。print(0)print(2)print(4)
  • (Python基础篇)字典的操作 EternityArt 基础篇python开发语言
    一、引言在Python编程中,字典(Dictionary)是一种极具灵活性的数据结构,它通过“键-值对”(key-valuepair)的形式存储数据,如同现实生活中的字典——通过“词语(键)”快速查找“释义(值)”。相较于列表和元组的有序索引访问,字典的优势在于基于键的快速查找,这使得它在处理需要频繁通过唯一标识获取数据的场景中极为高效。掌握字典的操作,能让我们更高效地组织和管理复杂数据,是Pyt
  • Python七彩花朵 Want595 python开发语言
    系列文章序号直达链接Tkinter1Python李峋同款可写字版跳动的爱心2Python跳动的双爱心3Python蓝色跳动的爱心4Python动漫烟花5Python粒子烟花Turtle1Python满屏飘字2Python蓝色流星雨3Python金色流星雨4Python漂浮爱心5Python爱心光波①6Python爱心光波②7Python满天繁星8Python五彩气球9Python白色飘雪10Pyt
  • php 高并发下日志量巨大,如何高效采集、存储、分析 贵哥的编程之路(热爱分享 为后来者) PHP语言经典程序100题php开发语言
    1.问题背景高并发系统每秒产生大量日志(如访问日志、错误日志、业务日志等)。单机写入、存储、分析能力有限,容易成为瓶颈。需要支持实时采集、分布式存储、快速检索与分析。2.主流架构方案一、分布式日志采集架构[应用服务器(PHP等)]|v[日志采集Agent(如Filebeat、Fluentd、Logstash)]|v[消息队列/缓冲(如Kafka、Redis、RabbitMQ)]|v[日志存储(如E
  • 用OpenCV标定相机内参应用示例(C++和Python)
    下面是一个完整的使用OpenCV进行相机内参标定(CameraCalibration)的示例,包括C++和Python两个版本,基于棋盘格图案标定。一、目标:相机标定通过拍摄多张带有棋盘格图案的图像,估计相机的内参:相机矩阵(内参)K畸变系数distCoeffs可选外参(R,T)标定精度指标(如重投影误差)二、棋盘格参数设置(根据自己的棋盘格设置):棋盘格角点数:9x6(内角点,9列×6行);每个
  • Anaconda 详细下载与安装教程
    Anaconda详细下载与安装教程1.简介Anaconda是一个用于科学计算的开源发行版,包含了Python和R的众多常用库。它还包括了conda包管理器,可以方便地安装、更新和管理各种软件包。2.下载Anaconda2.1访问官方网站首先,打开浏览器,访问Anaconda官方网站。2.2选择适合的版本在页面中,你会看到两个主要的下载选项:AnacondaIndividualEdition:适用于
  • python中 @注解 及内置注解 的使用方法总结以及完整示例 慧一居士 Pythonpython
    在Python中,装饰器(Decorator)使用@符号实现,是一种修改函数/类行为的语法糖。它本质上是一个高阶函数,接受目标函数作为参数并返回包装后的函数。Python也提供了多个内置装饰器,如@property、@staticmethod、@classmethod等。一、核心概念装饰器本质:@decorator等价于func=decorator(func)执行时机:在函数/类定义时立即执行装饰
  • Python中的静态方法和类方法详解
    在Python中,`@staticmethod`和`@classmethod`是两种装饰器,它们用于定义类中的方法,但是它们的行为和用途有所不同。###@staticmethod`@staticmethod`装饰器用于定义一个静态方法。静态方法不接收类或实例的引用作为第一个参数,因此它不能访问类的状态或实例的状态。静态方法可以看作是与类关联的普通函数,但它们可以通过类名直接调用。classMath
  • Python中类静态方法:@classmethod/@staticmethod详解和实战示例
    在Python中,类方法(@classmethod)和静态方法(@staticmethod)是类作用域下的两种特殊方法。它们使用装饰器定义,并且与实例方法(deffunc(self))的行为有所不同。1.三种方法的对比概览方法类型是否访问实例(self)是否访问类(cls)典型用途实例方法✅是❌否访问对象属性类方法@classmethod❌否✅是创建类的替代构造器,访问类变量等静态方法@stati
  • Python多版本管理与pip升级全攻略:解决冲突与高效实践 码界奇点 Pythonpythonpip开发语言python3.11源代码管理虚拟现实依赖倒置原则
    引言Python作为最流行的编程语言之一,其版本迭代速度与生态碎片化给开发者带来了巨大挑战。据统计,超过60%的Python开发者需要同时维护基于Python3.6+和Python2.7的项目。本文将系统解决以下核心痛点:如何安全地在同一台机器上管理多个Python版本pip依赖冲突的根治方案符合PEP标准的生产环境最佳实践第一部分:Python多版本管理核心方案1.1系统级多版本共存方案Wind
  • 蓝牙MTU含义 ,协商修改的过程案例分析 悟空胆好小 嵌入式硬件网络人工智能
    蓝牙MTU含义,协商修改的过程案例分析文章目录**蓝牙MTU含义,协商修改的过程案例分析****一、MTU含义解析****二、MTU协商过程详解****步骤流程****三、修改MTU的实践案例分析****案例1:中心设备主动设置(主控端)****案例2:外设端响应优化(从设备)****案例3:调试工具强制修改****四、关键限制与注意事项**蓝牙MTU(MaximumTransmissionUni
  • 基于Python的健身数据分析工具的搭建流程day1 weixin_45677320 python开发语言数据挖掘爬虫
    基于Python的健身数据分析工具的搭建流程分数据挖掘、数据存储和数据分析三个步骤。本文主要介绍利用Python实现健身数据分析工具的数据挖掘部分。第一步:加载库加载本文需要的库,如下代码所示。若库未安装,请按照python如何安装各种库(保姆级教程)_python安装库-CSDN博客https://blog.csdn.net/aobulaien001/article/details/133298
  • seaborn又一个扩展heatmapz qq_21478261 #Python可视化matplotlib
    推荐阅读:Pythonmatplotlib保姆级教程嫌Matplotlib繁琐?试试Seaborn!
  • NGS测序基础梳理01-文库构建(Library Preparation) qq_21478261 #生物信息生物学
    本文介绍Illumina测序平台文库构建(LibraryPreparation)步骤,文库结构。写作时间:2020.05。推荐阅读:10W字《Python可视化教程1.0》来了!一份由公众号「pythonic生物人」精心制作的PythonMatplotlib可视化系统教程,105页PDFhttps://mp.weixin.qq.com/s/QaSmucuVsS_DR-klfpE3-Q10W字《Rg
  • Python 常用内置函数详解(七):dir()函数——获取当前本地作用域中的名称列表或对象的有效属性列表
    目录一、功能二、语法和示例一、功能dir()函数获取当前本地作用域中的名称列表或对象的有效属性列表。二、语法和示例dir()函数有两种形式,如果没有实参,则返回当前本地作用域中的名称列表。如果有实参,它会尝试返回该对象的有效属性列表。如果对象有一个名为__dir__()的方法,那么该方法将被调用,并且必须返回一个属性列表。dir()函数的语法格式如下:C:\Users\amoxiang>ipyth
  • pythonjson中list操作_Python json.dumps 特殊数据类型的自定义序列化操作
    场景描述:Python标准库中的json模块,集成了将数据序列化处理的功能;在使用json.dumps()方法序列化数据时候,如果目标数据中存在datetime数据类型,执行操作时,会抛出异常:TypeError:datetime.datetime(2016,12,10,11,04,21)isnotJSONserializable那么遇到json.dumps序列化不支持的数据类型,该怎么办!首先,
  • Python 日期格式转json.dumps的解决方法 douyaoxin pythonjson开发语言
    classDateEncoder(json.JSONEncoder):defdefault(self,obj):ifisinstance(obj,datetime.datetime):returnobj.strftime('%Y-%m-%d%H:%M:%S')elifisinstance(obj,datetime.date):returnobj.strftime("%Y-%m-%d")json.d
  • Python 爬虫实战:视频平台播放量实时监控(含反爬对抗与数据趋势预测) 西攻城狮北 python爬虫音视频
    一、引言在数字内容蓬勃发展的当下,视频平台的播放量数据已成为内容创作者、营销人员以及行业分析师手中极为关键的情报资源。它不仅能够实时反映内容的受欢迎程度,更能在竞争分析、营销策略制定以及内容优化等方面发挥不可估量的作用。然而,视频平台为了保护自身数据和用户隐私,往往会设置一系列反爬虫机制,对数据爬取行为进行限制。这就向我们发起了挑战:如何巧妙地突破这些限制,同时精准地捕捉并预测播放量的动态变化趋势
  • 矩阵求逆(JAVA)利用伴随矩阵 qiuwanchi 利用伴随矩阵求逆矩阵
    package gaodai.matrix; import gaodai.determinant.DeterminantCalculation; import java.util.ArrayList; import java.util.List; import java.util.Scanner; /** * 矩阵求逆(利用伴随矩阵) * @author 邱万迟
  • 单例(Singleton)模式 aoyouzi 单例模式Singleton
    3.1           概述 如果要保证系统里一个类最多只能存在一个实例时,我们就需要单例模式。这种情况在我们应用中经常碰到,例如缓存池,数据库连接池,线程池,一些应用服务实例等。在多线程环境中,为了保证实例的唯一性其实并不简单,这章将和读者一起探讨如何实现单例模式。 3.2
  • [开源与自主研发]就算可以轻易获得外部技术支持,自己也必须研发 comsci 开源
          现在国内有大量的信息技术产品,都是通过盗版,免费下载,开源,附送等方式从国外的开发者那里获得的。。。。。。        虽然这种情况带来了国内信息产业的短暂繁荣,也促进了电子商务和互联网产业的快速发展,但是实际上,我们应该清醒的看到,这些产业的核心力量是被国外的
  • 页面有两个frame,怎样点击一个的链接改变另一个的内容 Array_06 UIXHTML
    <a src="地址"  targets="这里写你要操作的Frame的名字" />搜索 然后你点击连接以后你的新页面就会显示在你设置的Frame名字的框那里 targerts="",就是你要填写目标的显示页面位置 ===================== 例如: <frame src=&
  • Struts2实现单个/多个文件上传和下载 oloz 文件上传struts
    struts2单文件上传:     步骤01:jsp页面 <!--在进行文件上传时,表单提交方式一定要是post的方式,因为文件上传时二进制文件可能会很大,还有就是enctype属性,这个属性一定要写成multipart/form-data,不然就会以二进制文本上传到服务器端-->   <form action="fileUplo
  • 推荐10个在线logo设计网站 362217990 logo
    在线设计Logo网站。 1、http://flickr.nosv.org(这个太简单) 2、http://www.logomaker.com/?source=1.5770.1 3、http://www.simwebsol.com/ImageTool 4、http://www.logogenerator.com/logo.php?nal=1&tpl_catlist[]=2 5、ht
  • jsp上传文件 香水浓 jspfileupload
    1. jsp上传 Notice: 1. form表单 method 属性必须设置为 POST 方法 ,不能使用 GET 方法 2. form表单 enctype 属性需要设置为 multipart/form-data 3. form表单 action 属性需要设置为提交到后台处理文件上传的jsp文件地址或者servlet地址。例如 uploadFile.jsp 程序文件用来处理上传的文
  • 我的架构经验系列文章 - 前端架构 agevs JavaScriptWeb框架UIjQuer
    框架层面:近几年前端发展很快,前端之所以叫前端因为前端是已经可以独立成为一种职业了,js也不再是十年前的玩具了,以前富客户端RIA的应用可能会用flash/flex或是silverlight,现在可以使用js来完成大部分的功能,因此js作为一门前端的支撑语言也不仅仅是进行的简单的编码,越来越多框架性的东西出现了。越来越多的开发模式转变为后端只是吐json的数据源,而前端做所有UI的事情。MVCMV
  • android ksoap2 中把XML(DataSet) 当做参数传递 aijuans android
    我的android app中需要发送webservice ,于是我使用了 ksop2 进行发送,在测试过程中不是很顺利,不能正常工作.我的web service 请求格式如下     [html]  view plain copy   <Envelope xmlns="http://schemas.
  • 使用Spring进行统一日志管理 + 统一异常管理 baalwolf spring
    统一日志和异常管理配置好后,SSH项目中,代码以往散落的log.info() 和 try..catch..finally 再也不见踪影! 统一日志异常实现类: [java]  view plain copy   package com.pilelot.web.util;      impor
  • Android SDK 国内镜像 BigBird2012 android sdk
    一、镜像地址: 1、东软信息学院的 Android SDK 镜像,比配置代理下载快多了。 配置地址, http://mirrors.neusoft.edu.cn/configurations.we#android 2、北京化工大学的: IPV4:ubuntu.buct.edu.cn  IPV4:ubuntu.buct.cn IPV6:ubuntu.buct6.edu.cn
  • HTML无害化和Sanitize模块 bijian1013 JavaScriptAngularJSLinkySanitize
    一.ng-bind-html、ng-bind-html-unsafe         AngularJS非常注重安全方面的问题,它会尽一切可能把大多数攻击手段最小化。其中一个攻击手段是向你的web页面里注入不安全的HTML,然后利用它触发跨站攻击或者注入攻击。         考虑这样一个例子,假设我们有一个变量存
  • [Maven学习笔记二]Maven命令 bit1129 maven
    mvn compile compile编译命令将src/main/java和src/main/resources中的代码和配置文件编译到target/classes中,不会对src/test/java中的测试类进行编译 MVN编译使用 maven-resources-plugin:2.6:resources maven-compiler-plugin:2.5.1:compile &nbs
  • 【Java命令二】jhat bit1129 Java命令
    jhat用于分析使用jmap dump的文件,,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言。 jhat默认开启监听端口7000的HTTP服务,jhat是Java Heap Analysis Tool的缩写 1. 用法: [hadoop@hadoop bin]$ jhat -help Usage: jhat [-stack <bool&g
  • JBoss 5.1.0 GA:Error installing to Instantiated: name=AttachmentStore state=Desc ronin47
    进到类似目录 server/default/conf/bootstrap,打开文件 profile.xml找到: Xml代码<bean    name="AttachmentStore"  class="org.jboss.system.server.profileservice.repository.AbstractAtta
  • 写给初学者的6条网页设计安全配色指南 brotherlamp UIui自学ui视频ui教程ui资料
    网页设计中最基本的原则之一是,不管你花多长时间创造一个华丽的设计,其最终的角色都是这场秀中真正的明星——内容的衬托     我仍然清楚地记得我最早的一次美术课,那时我还是一个小小的、对凡事都充满渴望的孩子,我摆放出一大堆漂亮的彩色颜料。我仍然记得当我第一次看到原色与另一种颜色混合变成第二种颜色时的那种兴奋,并且我想,既然两种颜色能创造出一种全新的美丽色彩,那所有颜色
  • 有一个数组,每次从中间随机取一个,然后放回去,当所有的元素都被取过,返回总共的取的次数。写一个函数实现。复杂度是什么。 bylijinnan java算法面试
    import java.util.Random; import java.util.Set; import java.util.TreeSet; /** * http://weibo.com/1915548291/z7HtOF4sx * #面试题#有一个数组,每次从中间随机取一个,然后放回去,当所有的元素都被取过,返回总共的取的次数。 * 写一个函数实现。复杂度是什么
  • struts2获得request、session、application方式 chiangfai application
    1、与Servlet API解耦的访问方式。 a.Struts2对HttpServletRequest、HttpSession、ServletContext进行了封装,构造了三个Map对象来替代这三种对象要获取这三个Map对象,使用ActionContext类。 ----->   package pro.action; import java.util.Map; imp
  • 改变python的默认语言设置 chenchao051 python
    import sys sys.getdefaultencoding()  可以测试出默认语言,要改变的话,需要在python lib的site-packages文件夹下新建: sitecustomize.py, 这个文件比较特殊,会在python启动时来加载,所以就可以在里面写上: import sys sys.setdefaultencoding('utf-8') &n
  • mysql导入数据load data infile用法 daizj mysql导入数据
    我们常常导入数据!mysql有一个高效导入方法,那就是load data infile 下面来看案例说明 基本语法: load data  [low_priority] [local] infile 'file_name txt' [replace | ignore] into table tbl_name [fields [terminated by't'] [OPTI
  • phpexcel导入excel表到数据库简单入门示例 dcj3sjt126com PHPExcel
    跟导出相对应的,同一个数据表,也是将phpexcel类放在class目录下,将Excel表格中的内容读取出来放到数据库中 <?php error_reporting(E_ALL); set_time_limit(0); ?> <html> <head> <meta http-equiv="Content-Type"
  • 22岁到72岁的男人对女人的要求 dcj3sjt126com
    22岁男人对女人的要求是:一,美丽,二,性感,三,有份具品味的职业,四,极有耐性,善解人意,五,该聪明的时候聪明,六,作小鸟依人状时尽量自然,七,怎样穿都好看,八,懂得适当地撒娇,九,虽作惊喜反应,但看起来自然,十,上了床就是个无条件荡妇。 32岁的男人对女人的要求,略作修定,是:一,入得厨房,进得睡房,二,不必服侍皇太后,三,不介意浪漫蜡烛配盒饭,四,听多过说,五,不再傻笑,六,懂得独
  • Spring和HIbernate对DDM设计的支持 e200702084 DAO设计模式springHibernate领域模型
    A:数据访问对象     DAO和资源库在领域驱动设计中都很重要。DAO是关系型数据库和应用之间的契约。它封装了Web应用中的数据库CRUD操作细节。另一方面,资源库是一个独立的抽象,它与DAO进行交互,并提供到领域模型的“业务接口”。    资源库使用领域的通用语言,处理所有必要的DAO,并使用领域理解的语言提供对领域模型的数据访问服务。
  • NoSql 数据库的特性比较 geeksun NoSQL
    Redis 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。目前由VMware主持开发工作。   1. 数据模型 作为Key-value型数据库,Redis也提供了键(Key)和值(Value)的映射关系。除了常规的数值或字符串,Redis的键值还可以是以下形式之一: Lists (列表) Sets
  • 使用 Nginx Upload Module 实现上传文件功能 hongtoushizi nginx
    转载自: http://www.tuicool.com/wx/aUrAzm   普通网站在实现文件上传功能的时候,一般是使用Python,Java等后端程序实现,比较麻烦。Nginx有一个Upload模块,可以非常简单的实现文件上传功能。此模块的原理是先把用户上传的文件保存到临时文件,然后在交由后台页面处理,并且把文件的原名,上传后的名称,文件类型,文件大小set到页面。下
  • spring-boot-web-ui及thymeleaf基本使用 jishiweili springthymeleaf
    视图控制层代码demo如下:   @Controller @RequestMapping("/") public class MessageController { private final MessageRepository messageRepository; @Autowired public MessageController(Mes
  • 数据源架构模式之活动记录 home198979 PHP架构活动记录数据映射
    hello!架构 一、概念 活动记录(Active Record):一个对象,它包装数据库表或视图中某一行,封装数据库访问,并在这些数据上增加了领域逻辑。 对象既有数据又有行为。活动记录使用直截了当的方法,把数据访问逻辑置于领域对象中。   二、实现简单活动记录 活动记录在php许多框架中都有应用,如cakephp。 <?php /** * 行数据入口类 *
  • Linux Shell脚本之自动修改IP pda158 linuxcentosDebian脚本
    作为一名 Linux SA,日常运维中很多地方都会用到脚本,而服务器的ip一般采用静态ip或者MAC绑定,当然后者比较操作起来相对繁琐,而前者我们可以设置主机名、ip信息、网关等配置。修改成特定的主机名在维护和管理方面也比较方便。如下脚本用途为:修改ip和主机名等相关信息,可以根据实际需求修改,举一反三! #!/bin/sh #auto Change ip netmask ga
  • 开发环境搭建 独浮云 eclipsejdktomcat
           最近在开发过程中,经常出现MyEclipse内存溢出等错误,需要重启的情况,好麻烦。对于一般的JAVA+TOMCAT项目开发,其实没有必要使用重量级的MyEclipse,使用eclipse就足够了。尤其是开发机器硬件配置一般的人。         &n
  • 操作日期和时间的工具类 vipbooks 工具类
       大家好啊,好久没有来这里发文章了,今天来逛逛,分享一篇刚写不久的操作日期和时间的工具类,希望对大家有所帮助。 /* * @(#)DataFormatUtils.java 2010-10-10 * * Copyright 2010 BianJing,All rights reserved. */ package test; impor