内容概述
本篇内容主要为前期工作与学习中遇到的一些问题或者使用方法的记录,前后无关联顺序,所以会看起来比较杂乱,后期会针对某个比较有意义的知识点进行扩充深入研究探讨。
杂货铺
1、抓取网页源码乱码处理
爬虫乱码处理
方式一(不是很准确)
import chardet
chardet_detect(r.content)
方式二(相对来说更准确些)
import cchardet
cchardet.detect(r.content)
rsp.encoding = chardet.detect(rsp.content).get(‘encoding’)
事例代码:
import requests
import cchardet
url = 'http://zgdysj.com/html/news/20190222/30452.shtml'
html = requests.get(url)
result = cchardet.detect(html.content)
html.encoding = result['encoding']
print(html.text)
print(html.encoding)
print(result)
2、mongo 去重后获取数量,mongo操作
distinct(‘comic_name’, {}).length
3、socket.setdefaulttimeout(t)
t:代表经过t秒后,如果还未下载成功,自动跳入下一次操作,此次下载失败。
4、 requests告警消除
requests.packages.urllib3.disable_warnings()
5、查询mongo某个层级下列表中某个元素
db.getCollection(‘book_list’).find({“web_list”:{"$elemMatch":{“domain_id”:“2”}}})
6、mongo正则regex
find({post_text:{$regex:“runoob”}})
7、 mongo 聚合操作
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
] );
for n, chapter in enumerate(chapter_list, start=1):
9、快速初始化类中字典
db_configs = {
'host': '127.0.0.1',
'port': '27017',
'db_name': 'mafengwo',
'user': ''
}
class MotorOperation:
def __init__(self):
self.__dict__.update(**db_configs)
if self.user:
self.motor_uri = f"mongodb://{self.user}:{self.passwd}@{self.host}:{self.port}/{self.db_name}?authSource={self.db_name}"
else:
self.motor_uri = f"mongodb://{self.host}:{self.port}/{self.db_name}"
可代替方法:
def __init__(self, **kwargs):
for key, value in kwargs.iteritems():
setattr(self, key, value)
10、 进度条使用方法 tqdm 包
from tqdm import tqdm
import time
d = {'loss':0.2,'learn':0.8}
for i in tqdm(range(50),desc='进行中',ncols=10,postfix=d): #desc设置名称,ncols设置进度条长度.postfix以字典形式传入详细信息
time.sleep(0.1)
11、对列表中元素进行操作
语法
map() 函数语法:
map(function, iterable, …)
参数
function – 函数
iterable – 一个或多个序列
以下实例展示了 map() 的使用方法:
def square(x) : # 计算平方数
… return x ** 2
…
map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
#提供了两个列表,对相同位置的列表数据进行相加
map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]
12、浏览器模拟包
在Python 3.x中你可以用MechanicalSoup,这个库融合了Mechanize和BeautifulSoup两个库的功能具体使用需要看源码
13、获取电脑本机系统核心数
import psutil
print(psutil.cpu_count(False))
获取cpu数量、线程数
import multiprocessing
print(multiprocessing.cpu_count())
14、python 函数注释新写法
Substring(self, s: str) -> int:
15: 判断文本中是否含有特殊字符
1、特殊字符判断
def if_contain_symbol(keyword):
symbols = "~!@#$%^&*()_+-*/<>,.[]\/"
for symbol in symbols:
if symbol in keyword:
return True
else:
return False
2、利用结巴分词,判断分词数,从概率层面,正常的文本分词率(文本长度/分词后个数)>2,而乱码字符则接近1
import jieba
def if_contain_chaos(keyword):
str_len = len(keyword)
seg_len = len(jieba.lcut(keyword))
if str_len / seg_len < 2:
return True
else:
return False
3、通过将字符串的unicode转化为GB2312来判断是否含有生僻字。即当转化发生异常即为包含生僻字或特殊的无法识别字符
def if_contain_chaos(keyword):
try:
keyword.encode("gb2312")
except UnicodeEncodeError:
return True
return False
16、zip打包与*解包
统计列表中存在最多的元素
from collections import Counter
a = ['1','','']
q = ['1','','']
w = ['3','','']
b = ['2','','']
aa = ['2','','']
bb = ['2','','']
x = [a, b, q, w, aa, bb]
print(list(zip(a, b, q, w, aa, bb)))
c = list(zip(a, b, q, w, aa, bb))
d = Counter(c[1])
print(d)
print(d.most_common(3))
* 号解包
print(list(zip(*x)))
17、小数随机
import random
print(random.uniform(0,10))
18、进程池、线程池异常问题查看方式
results = [pool.apply_async(self.func) for _ in range(10)]
for res in results:
print(res.get()) #打印运行结果,异常问题会报错
threadpool线程池尽量不要使用,会出现内存泄露,内存溢出问题
进程池与线程池只有在调用close方法时才会释放内存,尽量不要一次性在一个池子中执行过多的操作。分批关闭重新创建池子释放内存,但也不能过于频繁的创建池子。
19、解决音频信息解析异常,不使用ffmpeg情况下
#若当前系统没有libmediainfo
yum install libmediainfo
Is this ok [y/d/N]: y
然后使用pymediainfo 包解析,导出json格式,获取对应信息
from pymediainfo import MediaInfo
mediaInfo = MediaInfo.parse(seed['out_put_path'])
song = json.loads(mediaInfo.to_json())
duration = int(int(song['tracks'][1]['duration']) / 1000)
byte = int(song['tracks'][1]['stream_size'])
20、实现实时同步:
inotify + rsync
安装 inotify :
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar zxf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14/
./configure && make && make install
如果提示libinotifytools.so.0相关异常
先安装一下libmediainfo 方法看19、
然后直接在安装目录使用inotifywait
编写shell 脚本:
#!/bin/bash
src=/data/app/python.test.book-script/books_chapter
des=data/app/php.test.reader-api/public
ip1=58.64.168.115
#ip2=58.64.168.116
user=saas
cd ${src}
/data/app/inotify-tools-3.14/src/inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ${src} | while read file
# 把监控到有发生更改的"文件路径列表"循环
do
INO_EVENT=$(echo $file | awk '{print $1}') # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
INO_FILE=$(echo $file | awk '{print $2}') # 把inotify输出切割 把文件路径部分赋值给INO_FILE
echo "-------------------------------$(date)------------------------------------"
echo $file
#增加、修改、写入完成、移动进事件
if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]] # 判断事件类型
then
echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
rsync -avzSH $(dirname ${INO_FILE}) "/"${des} &&
# INO_FILE变量代表路径哦 -c校验文件内容
rsync -avzSH $(dirname ${INO_FILE}) ${ip1}::${des}
fi
# 删除、移动出事件
if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
then
echo 'DELETE or MOVED_FROM'
rsync -avzSH --delete $(dirname ${INO_FILE}) "/"${des} &&
rsync -avzSH --delete $(dirname ${INO_FILE}) ${ip1}::${des}
fi
# 修改属性事件 指 touch charp chmod chown 等操作
if [[ $INO_EVENT =~ 'ATTRIB' ]]
then
echo 'ATTRIB'
if [ ! -d "$INO_FILE" ]
then
rsync -avzSH $(dirname ${INO_FILE}) "/"${des} &&
rsync -avzSH $(dirname ${INO_FILE}) ${ip1}::${des}
fi
fi
done
21,异步模块使用模式
import asyncio
class DownloadImage(object):
async def start(self):
tasks = []
for i in range(1, 10000):
tasks.append(self.set_img_data(i))
await asyncio.wait(tasks)
async def set_img_data(self, i):
print(i)
await asyncio.sleep(20)
if __name__ == '__main__':
spider = DownloadImage()
loop = asyncio.get_event_loop()
loop.run_until_complete(spider.start())
22、堆栈,堆,栈,队列的区别
②堆是在程序运行时,而不是在程序编译时,申请某个大小的内存空间。即动态分配内存,对其访问和对一般内存的访问没有区别。
③堆是应用程序在运行的时候请求操作系统分配给自己内存,一般是申请/给予的过程。
④堆是指程序运行时申请的动态内存,而栈只是指一种使用堆的方法(即先进后出)。
①栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。
②栈就是一个桶,后放进去的先拿出来,它下面本来有的东西要等它出来之后才能出来(先进后出)
③栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有FIFO的特性,在编译的时候可以指定需要的Stack的大小。
注意:其实堆栈本身就是栈,只是换了个抽象的名字
1.堆栈空间分配
①栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
②堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
①队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
②队列中没有元素时,称为空队列。
③建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针front,它指向队头元素;另一个是队尾指针rear,它指向下一个入队元素的存储位置。
④队列采用的FIFO(first in first out),新元素(等待进入队列的元素)总是被插入到链表的尾部,而读取的时候总是从链表的头部开始读取。每次读取一个元素,释放一个元素。所谓的动态创建,动态释放。因而也不存在溢出等问题。由于链表由结构体间接而成,遍历也方便。(先进先出)
23、Mongo聚合操作大量数据,报错出现内存超出32Mb:
解决方法:
1、 报错原因是内存不够,那么进行修改配置默认内存空间
2、 根据内容提示,为排序字段创建索引
3、 或者直接允许调用磁盘空间进行排序
# 为时间排序字段创建索引
db.collection.createIndex({"input_time":-1})
# 修改默认配置的内存空间为320M
db.adminCommand({setParameter:1, internalQueryExecMaxBlockingSortBytes:335544320})
加入allowDiskUse,允许调用磁盘空间
Mongo 命令实例:.aggregate(aggregate,{"allowDiskUse":true})
python 代码操作:.aggregate(aggregate, allowDiskUse=True)
24、Mongo在当前数据基础增加前缀,使用Mongo调用函数,(小批量可执行,数据过多会超时15s):
db.getCollection(‘mangguo_20201112_log’).find({“gender” : “女”}).forEach(
function(item){
db.getCollection(‘mangguo_20201112_log’).update({"_id":item.id},{$set:{“user_name”:
"nv"+item.name}})
}
)
25、图片去水印知识点学习:去动态位置水印等等,需要学习,此处为知识点补充。
26、图片类加密手段
1、打开文本格式,内容增加key,解析时删除对应key。
2、内容信息做偏移,0>1, 解密时:把1>0,类似这种手法,实际操作切记源文件中判断是否已存在此标记。
27、linux 系统 sh脚本执行异常报错syntax error: unexpected end of file,处理方案
:set ff 查看文档格式(若默认为dos则需修改,linux下需执行unix格式)
":set ff=unix"保存后再次执行即可
28、.env 的使用:
.env文件建议放在项目根目录下,存储格式NAME="lanfeng",尽可能使用引号
安装:pip install python-dotenv
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv(), override=True)
Jenkins(os.getenv('jenkins_url'),username=os.getenv('jenkins_user'))
29、scrapy不同的爬虫使用settings,独立设置在parse时调用custom_settings
custom_settings = {
'ITEM_PIPELINES':{'quotetutorial.pipelines.MongoPipeline': 400,}, 'DEFAULT_REQUEST_HEADERS':{
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)',
'Accept-Encoding': 'gzip,deflate',
'Accept-Language': 'zh-cn,zh,en'
} }
parse()
30、信息量计算公式:
设事件A发生的概率是P(A),则事件A的信息量为:
信息量的单位是比特(bit),一个比特是一位二进制数
世界杯32强角逐之前的冠军竞猜,问:
回答正确者的信息量是多少?
-log2(1/32) = -log10(1/32)/log10(2) =