Python使用技巧2
python url网址拼接
在做爬虫中,经常会遇到需要把一个域名和网址路径进行拼接,在开发时一时没想到方法,特此记录下来。
利用parse.urljoin方法进行网址拼接
from urllib import parse
print(parse.urljoin("http://www.chenxm.cc", "abc.html"))
print(parse.urljoin("http://www.chenxm.cc/", "/../../abc.html"))
print(parse.urljoin("http://www.chenxm.cc/post", "./../../abc.html"))
>>> http://www.chenxm.cc/abc.html
>>> http://www.chenxm.cc/abc.html
>>> http://www.chenxm.cc/abc.html
python3 获取当前运行函数名称和类方法名称
如何获取当前运行函数(或方法)的名称呢?
背景:python3.8
第一种方法:
利用__name__获取当前方法名称
def create():
print("hello word")
print(create.__name__)
>>> create
第二种方法:利用sys获取当前方法名称
import sys
def create():
print(f"当前方法名:{sys._getframe().f_code.co_name}")
create()
>>> 当前方法名:create
获取类的名称以及当前方面名称
import sys
class Object():
def filter(self,*args, **kwargs):
return Filter(*args, **kwargs)
def create(self):
print(f'当前类名称:{self.__class__.__name__}')
print(f"当前方法名:{sys._getframe().f_code.co_name}")
o=Object()
o.create()
>>> 当前类名称:Object
>>> 当前方法名:create
python 字符串转换成字节,字节转换成十六进制
python 字符串转换成字节,字节转换成十六进制
背景:
python3.8
s="aaabbbccc"
# 将字符串转换字节
s_bytes=s.encode()
print(f'数据类型:{type(s_bytes)},输出数据:{s_bytes}')
>>> 数据类型:<class 'bytes'>,输出数据:b'aaabbbccc'
# 将十进制字符串转换为十六进制字符串
h_str=s_bytes.hex()
print(f'数据类型:{type(h_str)},输出数据:{h_str}')
>>> 数据类型:<class 'str'>,输出数据:616161626262636363
print(binascii.hexlify(s_bytes))
>>> 616161626262636363
# 将十六进制字符串转换成字节
h_bytes=bytes.fromhex(h_str)
print(f'数据类型:{type(h_bytes)},输出数据:{h_bytes}')
>>> 数据类型:<class 'bytes'>,输出数据:aaabbbccc'
print(binascii.unhexlify(h_str))
>>> aaabbbccc
print(bytes([0,1,2,3,4,5]).hex())
>>> 000102030405
print(bytes.fromhex('000102030405'))
>>> b'\x00\x01\x02\x03\x04\x05'
print(b'abcde'.hex())
>>> 6162636465
print(bytes.fromhex('6162636465'))
>>> b'abcde'
python 把pdf转成图片文件
Wand是ctypes基于Python 的简单ImageMagick绑定。
1. 安装wand包:
pip install Wand
文档网址:http://docs.wand-py.org/en/0.6.1/
2. 安装ImageMagick
window电脑需要预装一个软件:http://docs.wand-py.org/en/latest/guide/install.html#install-imagemagick-on-windows
其他系统ImageMagick请参考文档:http://docs.wand-py.org/en/latest/guide/install.htm
注意:在选择ImageMagick32位还是64位,这个需要和python的位数一致。参考文章:查看python是32位还是64位
2.1 安装时需要注意勾选Install development headers and libraries for C and C++ 。
2.2 安装后设置MAGICK_HOME环境变量,值为imagemagick的安装路径,并将安装路径加入path。
环境变量设置流程:我的电脑(右键我的电脑)→属性→高级系统设置→环境变量→新建
3. 安装ghostscript
下载ghostscript时选择AGPL release,注意32位还是64位。
把pdf转换成图片样例:
from wand.image import Image as wi
pdf=wi(filename='文件.pdf',resolution=300)
pdf_image=pdf.convert('jpeg')
i=1
for img in pdf_image.sequence:
page=wi(image=img)
page.save(finename=f'{i}.jpg')
i+=1
注意:上述把pdf转换成图片代码比较简单,但是只能处理页数较少的pdf还行,如果页数太多会卡住。建议使用pyPDF2分割pdf然后转换再转换成图片。
python python-pptx对pptx文件读取示例
python python-pptx对pptx文件读取示例,以下是如何使用pptx.Presentation()的代码示例。
python-pptx安装:
pip install python-pptx
官网文档:
https://python-pptx.readthedocs.io/en/latest/index.html
代码:
from pptx import Presentation
# 打开pptx文件
prs=Presentation(r'C:\Users\admin\Desktop\test\演示文稿1.pptx')
# 遍历每一页的幻灯片
for slide in prs.slides:
# 遍历每一个幻灯片的形状
for shape in slide.shapes:
# 判断该形状是否是一个文字框架
if not shape.has_text_frame:
continue
for paragraph in shape.text_frame.paragraphs:
# 拼接文字
print(''.join(run.text for run in paragraph.runs))
参考文章:
https://www.programcreek.com/python/example/105890/pptx.Presentation
python 读取word文件 docx2txt和textract
python 读取word文件 docx2txt和textract
docx2txt安装
pip install docx2txt
docx2txt代码:
import docx2txt
my_text=docx2txt.process(r'C:\test\疫情防控思政大课观后感.docx')
print(my_text)
注意:docx2tx只支持word后缀为docx,不支持doc
如果需要支持doc,建议使用模块:textract
textract安装:
pip install textract
官方文档:https://textract.readthedocs.io/en/stable/
使用代码:
import textract
text = textract.process("path/to/file.extension")
python 复杂递归问题 汉诺塔
汉诺塔问题是法国数学家Edouard Lucas于1883年,根据传说提出来的。
传说在一个印度教寺庙里,有3根柱子,其中一根套着64个有小到大的黄金盘片,僧侣们的任务就是把这一叠黄建盘从一根柱子搬到另一根,但有两个规则:
-
一次只能搬一个板子
-
大盘子不能叠在小盘子上
神的旨意说一旦这些盘子完成迁移,寺庙将会坍塌,世界将会毁灭。
递归逻辑
将盘片塔从开始柱,经由中间柱,移动到目标柱
-
将上层N-1个盘片的盘片塔,从开始柱,经由目标柱,移动到中间柱;
-
将第N个(最大的)盘片,从开始柱,移动到目标柱;
-
最后将放置在中间柱的N-1个盘片的盘片塔,经由开始柱,移动到目标柱。
基本结束条件,也就是最小规模问题:
-
一个盘片的移动
代码:
def move_tower(height,from_pole,with_pole,to_pole):
if height>=1:
move_tower(height-1,from_pole,to_pole,with_pole)
move_disk(height,from_pole,to_pole)
move_tower(height-1,with_pole,from_pole,to_pole)
def move_disk(disk,from_pole,to_pole):
print(f'moving disk {disk} from {from_pole} to {to_pole}')
move_tower(3,'#1','#2','#3')
输出结果
moving disk 1 from #1 to #3
moving disk 2 from #1 to #2
moving disk 1 from #3 to #2
moving disk 3 from #1 to #3
moving disk 1 from #2 to #1
moving disk 2 from #2 to #3
moving disk 1 from #1 to #3
调整python中的递归深度限制
调整python中的递归深度限制
import sys
# 获取当前最大递归深度
sys.getrecursionlimit()
>>> 1000
# 设置当前你最大递归深度
sys.setrecursionlimit(3000)
sys.getrecursionlimit()
>>> 3000
递归 数列求和
递归三大定律
-
递归算法必须有一个基本结束条件(最小规模问题的直接解决)
-
递归算法必须能改变状态向基本结束条件演进(减少问题规模)
-
递归算法必须调用自身(解决减少了规模的相同的问题)
递归 数列求和
def listSum(li):
if len(li)==1:
return li[0] #最小规模
return li[0]+listSum(li[1:]) # 调用自身
print(listSum([1,2,3]))
print(listSum([1,2,3,4,5]))
print(listSum([1,2,3,4,5,6,7]))
输出结果:
6
13
28
python 读取指定文件夹下所有文件名
递归获取指定文件下的所有文件的绝对路径
import os
def get_files(dir_path, file_names=[]):
"""获取某路径下所有文件列表
:type dir_path: str
:param dir_path: 真实存在的路径
:type file_names: list
:param file_names: 文件名保存列表,依赖调用端构造传递
:return:
"""
# 绝对路径
if not os.path.isabs(dir_path):
dir_path = os.path.abspath(dir_path)
for (path_name, dirs, files) in os.walk(dir_path):
if files: # 文件,则添加进列表
for f in files:
file_names.append(os.path.join(path_name, f))
if dirs: # 目录,递归获取
for dir_ in dirs:
get_files(os.path.join(path_name, dir_), file_names)
else:
return file_names
file_li=get_files(r'C:\Users\pala\Downloads')
print("-"*100)
print(len(file_li),file_li)
python 更快创建一个随机整数的列表
python 如何更快创建一个随机整数的列表?
普通方法(最慢):
import random
li=[random.randint(0, 1000) for r in xrange(10000)]
利用random.sample(中等):
import random
random.sample(range(10000), 10000)
利用numpy.random(最快):
import numpy.random as nprnd
nprnd.randint(1000, size=10000)
测试结果如下:
import numpy.random as nprnd
import timeit
t1 = timeit.Timer('[random.randint(0, 1000) for r in xrange(10000)]', 'import random') # v1
t2 = timeit.Timer('random.sample(range(10000), 10000)', 'import random') # v2
t3 = timeit.Timer('nprnd.randint(1000, size=10000)', 'import numpy.random as nprnd') # v3
print t1.timeit(1000)/1000
print t2.timeit(1000)/1000
print t3.timeit(1000)/100
具体时间如下:
0.0131397729926
0.00475841206447
0.00055090731109
python获取当前计算机的cpu数量
python获取当前计算机的cpu数量
import multiprocessing
print(multiprocessing.cpu_count())
>>> 16
selenium 实现上传图片/文件多种方法
个人在写脚本时遇到需要selenium来上传图片。
第一种方法:
一般比较简单的网站可以使用以下方法(只使用非常简单的网站):
browser.find_element_by_id("IdOfInputTypeFile").send_keys(os.getcwd()+"/image.png")
browser.find_element_by_xpath("IdOfInputTypeFile").send_keys(os.getcwd()+"/image.png")
第二种方法 使用pyautogui或者是autoit
import autoit
autoit.win_active("Open")
autoit.control_send("Open","Edit1",r"C:\Users\uu\Desktop\TestUpload.txt")
autoit.control_send("Open","Edit1","{ENTER}")
# 建议使用control_set_text 因为control_send会发送错误的文本
autoit.control_set_text("Open","Edit1",r"C:\Users\uu\Desktop\TestUpload.txt")
或者是
import autoit
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
ActionChains(driver).move_to_element( driver.find_element_by_xpath("//path/to/upload/button")).click().perform()
handle = "[CLASS:#32770; TITLE:Open]"
autoit.win_wait(handle, 60)
autoit.control_set_text(handle, "Edit1", "\\file\\path")
autoit.control_click(handle, "Button1")
第三种方法 使用pywin32
import win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
shell.Sendkeys("C:\text.txt")
shell.Sendkeys("~")
第二和第三种方法都有一点小问题时,就是当电脑在被使用时,会影响实际操作的结果。
python 判断年份是否为闰年
判断闰年的标准是:1、能整除4且不能整除100 2、能整除400
if year % 4 == 0 and year % 100 != 0:
print 'yes'
elif year % 400 == 0:
print u"yes"
else:
print u"no"
python并发编程--多进程模块 multiprocessing
由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。
multiprocessing包是Python中的多进程管理包。与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。该进程可以运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。
一、进程调用方法两种方法:
第一种代码示例:
from multiprocessing import Process
import time
def f(name):
time.sleep(1)
print('hello', name,time.ctime())
if __name__ == '__main__':
p_list=[]
for i in range(3):
p = Process(target=f, args=('alvin',))
p_list.append(p)
p.start()
for i in p_list:
p.join()
print('end')
第二种代码示例:
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self):
super(MyProcess, self).__init__()
#self.name = name
def run(self):
time.sleep(1)
print ('hello', self.name,time.ctime())
if __name__ == '__main__':
p_list=[]
for i in range(3):
p = MyProcess()
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('end')
显示单个进程的ID代码示例:
from multiprocessing import Process
import os
import time
def info(title):
print("title:",title)
print('parent process:', os.getppid())
print('process id:', os.getpid())
def f(name):
info('function f')
print('hello', name)
if __name__ == '__main__':
info('main process line')
time.sleep(1)
print("------------------")
p = Process(target=info, args=('yuan',))
p.start()
p.join()
输出结果:
title: main process line
parent process: 8368 # 在pycharm中运行,所以该线程是pycharm
process id: 8756 # info 进程
------------------
title: yuan
parent process: 8756 # info创建的进程
process id: 4300
二、Process类
构造方法:
Process([group [, target [, name [, args [, kwargs]]]]])
group: 线程组,目前还没有实现,库引用中提示必须是None;
target: 要执行的方法;
name: 进程名;
args/kwargs: 要传入方法的参数。
实例方法:
is_alive():返回进程是否在运行。
join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。
start():进程准备就绪,等待CPU调度
run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。
terminate():不管任务是否完成,立即停止工作进程
属性:
daemon:和线程的setDeamon功能一样
name:进程名字。
pid:进程号。