python模块使用记录

目前使用到的模块有:

  • json
  • configparser
  • 文件读写
  • os
  • sys
  • re
  • BeautifulSoup
  • requests
  • collections
  • scapy
  • webdriver

json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import json
path = 'F:/json.txt'
_dict = {'key1':'value1', 'key2':'value2'}
#将python数据类型转化为json字符串并写入到txt文件中
fw = open(path, 'w')
str = json.dumps(_dict) #从python类型转化到json字符串的函数
fw.write(str)
fw.close()
#从txt文件中提取json字符串并转化为python数据类型
fr = open(path, 'r')
str = fr.read()
_dict = json.loads(str) #从json字符串转化到python字典类型的函数
fr.close()
#一个可以将多个变量作为字典转成json格式的函数,使用python可变参数实现
def json_encode(**kwargs):
return json.dumps(kwargs)
str = json_encode(var1 = 'Yiruma', var2 = {'light':'music'}, var3 = [1,'2'])


configparser

本来学了想用作python的配置文件存储,结果后来一想还是用json存吧,方便不同语言间操作,先记录下来以备后用
这是python3的操作方法,具体python2的操作还不太一样,python2走这里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import configparser
#configparser写配置:
fw = open('F:/crawler.ini', 'w')
config = configparser.ConfigParser()
config['key1'] = {"var1":'1', "var2":'2'}
config['key2'] = {"var3":'3', "var4":'4'}
config.write(fw)
fw.close()
#configparser读取配置
config = configparser.ConfigParser()
config.read('F:/crawler.ini')
config_var = config.sections()
/**
注释:Config parsers do not guess datatypes of values in configuration files, always storing them internally as strings. This means that if you need other datatypes, you should convert on your own:
在存储的配置文件中,所有的数据都是以字符串形式存储的
*/


文件读写

1
2
3
4
5
6
7
8
9
10
f = open(file_path, mode)
文件打开的模式有:
r 只读方式打开,函数f.read()返回所有 f.readlines()返回列表
w 只写方式打开,注意会覆盖原来的文件,函数f.write()写入数据
a 追加方式打开,指针在文件的末尾,函数f.write()写入数据
rb, wb, ab 都是以二进制格式来读写文件
r+, w+, a+ 都是打开文件用于读写

os操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import os
#调用命令行
os.system()
#检查目录或文件是否存在,并返回bool值,python2中注意参数编码需为gbk
os.path.exists(path)
#列出目录下所有的文件名
os.listdir(path)
#判断是否是目录
os.path.isdir()
#判断是否是文件
os.path.isfile()
#创建文件夹
os.makedir()
#创建多级文件夹
os.makedirs()
#文件重命名
os.rename(old, new)
#文件删除
os.remove()
#获取当前工作目录
os.getcwd()
#分离文件名
os.path.split(r"c:\python\hello.py") --> ("c:\\python", "hello.py")
#分离扩展名
os.path.splitext(r"c:\python\hello.py") --> ("c:\\python\\hello", ".py")

sys

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sys
if __name__ == "__main__":
#首先为只有两个参数下的可能的两个场景(version,help)做出解释,之后退出
if len(sys.argv) == 2 and sys.argv[1].startswith('--'):
option = sys.argv[1][2:]
if option == 'version':
print ('Version 1.0')
elif option == 'help':
print ('usage python crawler.py blog_nick original_url page_reg article_reg title')
else:
print ('Unknown option')
exit()
#再为参数个数非6的情况做出解释,告知正确的参数格式
elif len(sys.argv) != 6:
print ('usage python crawler.py blog_nick original_url page_reg article_reg title')
exit()
#确定拥有正常个数的参数,接下来就是正常的操作了
...
...

re

更详细的操作方法见https://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html

1
2
3
4
5
6
7
8
9
10
import re
#创建正则表达式,我一般习惯这样书写,可以方便重复使用,毕竟构造正则表达式是很耗费时间的
reg = re.complie('xxx')
#正则表达式的方法:
reg.findall(str) #匹配所有匹配到的字符串,并返回一个列表
reg.sub(new, str) #将str中所有匹配到的字符串都用new来替换
reg.search(str) #用于搜索,如果没有搜索到时返回None,搜索到时返回Match对象
Match对象:在reg.Match() reg.search()中都可能返回此对象,包含多种可读属性与方法




bs4.beautifulsoup

最全的操作方法见https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

1
2
3
4
5
6
7
8
9
10
11
12
from bs4 import BeautifulSoup
#建立BeautifulSoup对象
html = s.get('http://cauc.me')
bs = BeautifulSoup(html, "html.parser")
#BeautifulSoup对象提供的选择器
bs.a bs.body bs.parent bs.children bs.next_sibling bs.previous_sibling
.findall(id=xxx) .findall(class=xxx) .findall('a')
#BeautifulSoup对象提供对标签的内容选择
.name节点名字 .string节点内容 .attrs节点属性


requests

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import requests
s = requests.session()
方法
#使用get方式提交
s.get(url="")
#使用post方式提交
s.post(url="",data=dict格式)
#headers参数介绍
headers以字典方式提交
s.post(url="",headers=dict格式)
常用的头有:X-Forwarded-For, Cookie, User-Agent等等
#timeout参数介绍
timeout参数用来指定请求超时的时间,经常在爬虫中用到
s.post(url="", timeout=xx)
返回值:
retu = s.get("http://cauc.me")
retu.context #返回的html文件
retu.headers #返回的headers中的信息,是一个字典
retu.status_code #返回http的状态值
#其他的返回值可以自己去测试下,都很简单,上面三个是经常用的

collections

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
collections是一个非常方便的python内建集合模块,提供了许多有用的集合类
#defaultdict
使用dict类型时,如果引用的key不存在,就会抛出KeyError一场,如果希望key不存在时,返回一个默认值,
就可以使用defaultdict,这在很多场景下会很有用,之前我就经常在统计类型个数的时候使用
from collections import defaultdict
dd = defaultdict(0)
dd['xie'] += 1
#namedtuple
有些时候需要创建一个包含数据类型的类,比如要创建二位坐标类,使用Point(1,2)就要使用(1,2)明白的多
from collections import namedtuple
point = namedtuple('point', ['x','y'])
p = point(1,2)
p.x
p.y
#除此之外还有的数据类型有:
双向列表deque来代替单向列表list
根据Key顺序对dict排序的OrderedDict
计数器Counter,但是我一般习惯使用defaultDict来取得同样的效果
ChinaMap 将map串联起来
UserDict
UserList
UserString

scapy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# 建立各种类型的包,构造函数并没有封装在类里,原理大概是类似于工厂方法式的初始化,
IP()
TCP()
ICMP()..
# 构造数据包,其实就是在为类里的成员变量传值
IP().src = "10.5.24.1"
TCP().dport = "https" ..
# 发送数据包,相关函数同样没有封装在类里
send(IP(),count = 100) 第三层的发包,也就是会在构造好的包上再用二层包封装起来,因此传入二层包时则会错误的包装成两层
sendp() 第二层的发包,用于发送二层包
# 展示包
IP().show() 格式化展示包
IP().show2() 格式化展示包,并且是计算之后等待发出的包了,比如包中的校验和已经计算完成
raw(IP()) 输出包的byte字符串,这是唯一一个输出等价于包数据,可直接用的数据
hexdump(IP()) 输出包的二进制相关信息
IP().summary() 输出包摘要
ls(IP()) 以字段值显示包,类似show()
IP(raw(IP())) 用raw(IP)的结果,用来初始化IP包,初始化好的包已经将None数据填充好了
可以使用sprintf格式化输出包的信息,手法类似模板引擎
IP.sprintf("%TCP.sport%-->%TCP.dport%")
sprintf支持{}语法,包里不确定有此层的话就将语句用{}包装起来,没有的话就自动不输出了
IP.sprintf("{TCP:%TCP.sport%}{ICMP:%IP.src% - %ICMP.type%}")
# 多层的包重载
scapy中可以使用/来构造一个多层的包,这时包的初始化函数会根据上下文重载,包的参数会动态配置
IP()/TCP()
# 配置等
conf.iface 显示所使用的网卡
conf.route 显示路由表
# 抓包
sniff()
#里面支持的参数有
count=10 #包个数
fliter=(tcp dst port 80) #使用BPF过滤器语法的过滤器
prn=(lambda x: ) #对接收到的数据包进行处理的函数
lfliter=(lambda x: ....) #对接收到的包使用python函数的过滤器
stop_fliter=(lambda x: x.haslayer(TCP)) #通过python函数的返回值,返回True后则会停止抓包
# 返回值为PackageList类型
@@ 发送一组包,并获得响应的包,可以用于探测,定制攻击等
# 发送相关函数
#注 如果发送成功则只发送一组包,如果发送失败(失败的定义是没有返回包),则会一直发送,直到Crtl+C停止
ans, unans = sr(IP(dst='www.baidu.com')/TCP(dport=80)/"GET / HTTP/1.0\r\n\r\n") # 返回值ans中存储发送的包以及返回的包。unans为未响应的包
ans = sr1(packet) #ans中只存储返回的包,如果没有响应自然就没有值
ans = srp(Ether()/ARP()) #用于二层发送一组包
# 展示包
ans[0][1] ans[0]选中成功返回的包中的第一组,ans[0][1]选中这组包中的应答包
在选中包或一组包之后即可输出
ans # 可以直观的看到接收到的一组包的情况
>> ans
<Results: TCP:1 UDP:0 ICMP:0 Other:0>
>> unans
<Results: TCP:0 UDP:0 ICMP:0 Other:0>
ans.summary() #显示详情,成功发送包的ans则显示从哪里到哪里
>> ans.summary()
IP / TCP 192.168.43.233:12346 > 151.101.72.133:http S / Raw ==> IP / TCP 151.101.72.133:http > 192.168.43.233:12346 SA
ans.make_table(lambda p: (p[0][IP].dst, p[0][TCP].dport, p[1].sprintf("{TCP:%TCP.flags%}"))) #对于发送多个端口,多个ip的,可以使用这个函数做个简易的表展示出来, 根据标志位观察包的接收情况
# 使用举例
exp1: 扫描1-254网段内80端口存活的主机,使用RandShort()产生随机的源端口
list = ["192.168.1."+str(i) for i in range(1,255)]
ans, unans = sr(IP(dst=list)/TCP(sport=RandShort(), dport=80))
exp2: 扫描端口的开放情况,使用RandShort()产生随机的源端口
list = [i for i in range(0,10000)]
ans, unans = sr(IP(dst="118.89.16.36")/TCP(sport=RandShort(), dport=list))
exp3: 发送ACK包, 测试结果返回RST的flag,因为ACK包是在SYN包之后才应该出现的,因此对方主机返回RST重置标志
ans, unans = sr(IP(dst="www.cauc.edu.cn")/TCP(sport=888, dport=[21,22,80,443], flags="A"))
exp4: 模拟dns查询
ans, unans(IP(dst="192.168.43.1")/UDP()/DNS(rd=1, qd=DNSQR(qname="www.baidu.com")))
ans[0][1] # 查看DNS返回的内容

webdriver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@@配置webdriver
# 设置webdriver的http请求头
webdriver.DesiredCapabilities.PHANTOMJS["phantomjs.page.customHeaders.X-Forwarded-For"] = "123.232.23.245"
@@指定驱动器,生成一个页面
# 为webdriver设置驱动器, 可选phantomJS, firefox, chrome,类似产生一个页面
driver = webdriver.PhantomJS(executable_path=r"G:\phantomjs\bin\phantomjs.exe")
@@对页面进行操作
# 页面driver请求url
driver.get("http://116.85.43.88:8080/KREKGJVFPYQKERQR/dfe3ia/index.php")
# 页面执行js代码,可以对页面的DOM进行操作
driver.execute_script("""document.getElementById('author').type = "text";""")
# 获取DOM中的元素
id = driver.find_element_by_id("id")
# 操作元素内容
sendId = raw_input("id:")
button.click()
@@打印页面当前信息
print driver.current_url
print driver.page_source
print driver.get_cookies()
print driver.title