python爬虫入门
JANUARY 23, 2018
学习mooc:https://www.icourse163.org/learn/BIT-1001870001
第一天:requests库的基本使用方法
requests有七个基本方法,分别是
方法 | 说明 |
---|---|
requests.request() | 构造一个请求,支撑以下各方法的基础方法 |
requests.get() | 获取HTML网页的主要方法,对应于HTTP的GET |
requests.head() | 获取HTML网页头信息的方法,对应于HTTP的HEAD |
requests.post() | 向HTML网页提交POST请求的方法,对应于HTTP的POST |
requests.put() | 向HTML网页提交PUT请求的方法,对应于HTTP的PUT |
requests.patch() | 向HTML网页提交局部修改请求,对应于HTTP的PATCH |
requests.delete() | 向HTML页面提交删除请求,对应于HTTP的DELETE |
除了第一个另外六个是对应的http协议对资源的操作,但是看源码可以发现,第二个到底七个方法都是调用的第一个方法,也可以说requests只有一个request方法
返回值是一个Response对象
属性 | 说明 |
---|---|
r.status_code | http请求的返回状态码,200表示成功,其他表示失败 |
r.text | HTTP响应内容的字符串形式,即,url对应的页面内容 |
r.encoding | 从HTTP header中猜测的响应内容编码方式 |
r.apparent_encoding | 从内容中分析出的响应内容编码方式(备选编码方式) |
r.content | HTTP响应内容的二进制形式 |
其中r.encoding是从请求头中得到的编码信息,如果header中不存在charset,则认为编码为ISO‐8859‐1, r.text根据r.encoding显示网页内容,可能不准确,r.apparent_encoding是从具体内容中分析出来的编码信息,可能更加准确
Requests异常
异常 | 说明 |
---|---|
requests.ConnectionError | 网络连接错误异常,如DNS查询失败、拒绝连接等 |
requests.HTTPError | HTTP错误异常 |
requests.URLRequired | URL缺失异常 |
requests.TooManyRedirects | 超过最大重定向次数,产生重定向异常 |
requests.ConnectTimeout | 连接远程服务器超时异常 |
requests.Timeout | 请求URL超时,产生超时异常 |
requests有一个专门处理异常的方法
r.raise_for_status()如果不是200,产生异常 requests.HTTPError
requests的爬虫基本框架
1 | import requests |
requests方法详解
requests.request(method, url, **kwargs)
method : 请求方式,对应get/put/post等7种
url : 拟获取页面的url链接
**kwargs: 控制访问的参数,共13个
∙ method : 请求方式
r = requests.request(‘GET’, url, **kwargs)
r = requests.request(‘HEAD’, url, **kwargs)
r = requests.request(‘POST’, url,**kwargs)
r = requests.request(‘PUT’, url, **kwargs)
r = requests.request(‘PATCH’, url, **kwargs)
r = requests.request(‘delete’, url, **kwargs)
r = requests.request(‘OPTIONS’, url, **kwargs)
∙ **kwargs: 控制访问的参数均为可选项
params : 字典或字节序列,作为参数增加到url中
kv = {‘key1’: ‘value1’, ‘key2’: ‘value2’}
r = requests.request(‘GET’, ‘http://python123.io/ws', params=kv)
print(r.url)
http://python123.io/ws?key1=value1&key2=value2
data : 字典、字节序列或文件对象,作为Request的内容
kv = {‘key1’: ‘value1’, ‘key2’: ‘value2’}
r = requests.request(‘POST’, ‘http://python123.io/ws', data=kv)
body = ‘主体内容’
r = requests.request(‘POST’, ‘http://python123.io/ws', data=body)
json : JSON格式的数据,作为Request的内容
kv = {‘key1’: ‘value1’}
r = requests.request(‘POST’, ‘http://python123.io/ws', json=kv)
headers : 字典,HTTP定制头
hd = {‘user‐agent’: ‘Chrome/10’}
r = requests.request(‘POST’, ‘http://python123.io/ws', headers=hd)
cookies : 字典或CookieJar,Request中的cookie
auth : 元组,支持HTTP认证功能
files : 字典类型,传输文件
fs = {‘file’: open(‘data.xls’, ‘rb’)}
r = requests.request(‘POST’, ‘http://python123.io/ws', files=fs)
timeout : 设定超时时间,秒为单位
r = requests.request(‘GET’, ‘http://www.baidu.com', timeout=10)
proxies : 字典类型,设定访问代理服务器,可以增加登录认证
pxs = { ‘http’: ‘http://user:pass@10.10.10.1:1234','https': ‘https://10.10.10.1:4321' }
r = requests.request(‘GET’, ‘http://www.baidu.com', proxies=pxs)
allow_redirects : True/False,默认为True,重定向开关
stream : True/False,默认为True,获取内容立即下载开关
verify : True/False,默认为True,认证SSL证书开关
cert : 本地SSL证书路径
python读取ini文件
DECEMBER 19, 2017
ini是一个保存程序设置的好东西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
48import configparser
cfg=configparser.ConfigParser()
cfg.read('test.ini')
'''
[database]
sql_url=123.206.26
sql_port=80
sql_user=root
sql_pass=123
[server]
url=xwmdream.cn
'''
#读取所有的节
cfg.sections()
#['database', 'server']
#列出节database下的元素
cfg.items('database')
#[('sql_url', '123.206.26'), ('sql_port', '80'), ('sql_user', 'root'), ('sql_pass', '123')]
#获取database节下的sql_url的值
cfg.get('database','sql_url')
#'123.206.26'
#设置database节下的test的值为456
cfg.set('database','test','456')
cfg.items('database')
#[('sql_url', '123.206.26'), ('sql_port', '80'), ('sql_user', 'root'), ('sql_pass', '123'), ('test', '456')]
#删除database节下的sql_pass的值
cfg.remove_option('database','sql_pass')
#删除database节
cfg.remove_section('database')
#保存到文件
f=open('new.ini','w')
cfg.write(f)
f.close()
#最后new.ini的结果
'''
[server]
url = xwmdream.cn
'''
python发送邮件 大全汇总
DECEMBER 18, 2017
参考菜鸟教程
发送只有文字的邮件
1 | import smtplib |
发送网页邮件
1 | import smtplib |
发送带有附件的邮件:
1 | import smtplib |
发送网页中带有图片的邮件
1 | import smtplib |
补充
上面的方法,发过去会显示由xxxx@qq.com代发
解决这个问题需要先引入1
2
3
4
5
6
7from email import encoders
from email.utils import formataddr,parseaddr
然后写入一个函数
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
然后将原本的1
2message['From'] = Header("发件人哦~", 'utf-8')#内容中显示的发件人
message['To'] = Header("收件人哦~", 'utf-8')#内容中显示的收件人
换成1
2message['From'] = _format_addr('发件人 <%s>'%sender)
message['To'] = _format_addr('收件人 <%s>'%receivers)
网页和python的握手
DECEMBER 7, 2017
使用websocket握手
网上找的例子,进行了优化
python代码: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
36import tornado.web
import tornado.websocket
import tornado.httpserver
import tornado.ioloop
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin):
return True
def open(self):
print('有人连接上我了')
def on_message(self, message):
print('接收到消息:'+message)
self.sendhh(message)
def on_close(self):
print('有人下线了')
def sendhh(self,mem):
print('我发送了消息:'+mem)
self.write_message(u""+mem)
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/', WebSocketHandler)
]
settings = { "template_path": "."}
tornado.web.Application.__init__(self, handlers, **settings)
if __name__ == '__main__':
ws_app = Application()
server = tornado.httpserver.HTTPServer(ws_app)
server.listen(1234)
tornado.ioloop.IOLoop.instance().start()
html代码: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
<html>
<head>
<meta charset="UTF-8">
<title>Tornado Websocket</title>
</head>
<script type="text/javascript">
var ws=null;
function setmem(hh){
document.getElementById('mem').innerHTML+=('<br/>'+hh);
}
function onLoad(){
ws = new WebSocket("ws://localhost:1234");
ws.onerror = function(e){
setmem('服务器连接失败');
ws.close();
ws=null;
}
ws.onmessage = function(e){
setmem('服务器说:'+e.data);
}
}
function sendMsg(){
if(ws==null){
document.getElementById('mem').style.color='red';
return;
}
ha=document.getElementById('msg').value;
ws.send(ha);
setmem('我说:'+ha);
}
window.onunload =function(){
if(ws!=null){
ws.close();
}
}
</script>
<body onload='onLoad();'>
Message to send: <input type="text" id="msg" />
<input type="button" onclick="sendMsg();" value="发送" />
<p id="mem"></p>
</body>
</html>
python使用tcp通讯
DECEMBER 5, 2017
python通过tcp通讯,
使用了简单的多线程
一个接收端最多允许两个发送端同时连接
上代码:
接收端
1 | import _thread |
发送端:
1 | import socket |
python正则表达式
NOVEMBER 28, 2017
python的re模块是用来匹配正则表达式的
re.compile(表达式)方法是根据正则表达式生成一个pattern对象,
pattern.match(str)生成一个match对象,这个对象包含了匹配到的结果
也可以直接使用re.match(表达式,str),直接生成一个match结果对象
具体更多的方法,http://www.runoob.com/python/python-reg-expressions.html
常用正则表达式:
[\u4e00-\u9fa5]匹配utf-8中文字符
^-?\d+$匹配整数形式字符串
[0-9][1-9][0-9]匹配正整数形式字符串
附上一个自己写的爬取必应每日一图的代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import time
import schedule
import re
import urllib.request
from time import strftime
from time import localtime
from time import time
def getbing():
req=urllib.request.urlopen('https://cn.bing.com')
buf=req.read()
an=re.findall(r'/az/hpr.+?.jpg',str(buf))
url='https://cn.bing.com'+an[0]
req=urllib.request.urlopen(url)
buf=req.read()
f=open("/home/wwwroot/default/bing/bing.jpg",'wb')
f.write(buf)
f.close()
print(strftime('%Y%m%d',localtime(time())),'获取成功')
schedule.every().day.at('06:00').do(getbing)
getbing()
while True:
schedule.run_pending()
linux下搭建安装python3
NOVEMBER 23, 2017
转自:http://blog.csdn.net/liang19890820/article/details/51079633
简述
CentOS 7 中默认安装了 Python,版本比较低(2.7.5),为了使用新版 3.x,需要对旧版本进行升级。
由于很多基本的命令、软件包都依赖旧版本,比如:yum。所以,在更新 Python 时,建议不要删除旧版本(新旧版本可以共存)。
版权所有:一去丶二三里,转载请注明出处:http://blog.csdn.net/liang19890820
查看 Python 版本号
当 Linux 上安装 Python 后(默认安装),只需要输入简单的命令,就可以查看 Python 的版本号:
python -V
写在前面:一定要先安装openssl!!!
1 | yum install openssl-devel |
下载新版本
进入 Python下载页面,选择需要的版本。
这里,我选择的版本是 3.5.2 。1
wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz
下载完成之后,进行解压缩:1
tar -zxvf Python-3.5.2.tgz
安装配置
进入解压缩后的目录,安装配置:
1 | cd Python-3.5.2/ |
执行 ./configure 时,如果报错:
configure: error: no acceptable C compiler found in $PATH
说明没有安装合适的编译器。这时,需要安装/升级 gcc 及其它依赖包。1
yum install make gcc gcc-c++
完成之后,重新执行:1
./configure --with-ssl --prefix=/usr/python3
编译 & 安装
配置完成之后,就可以编译了:1
make
漫长的等待……完成后,安装:1
make install
错误:
can’t decompress data; zlib not available
解决办法:yum -y install zlib*
ModuleNotFoundError: No module named ‘_ctypes’
解决办法#yum install libffi-devel -y
设置 3.x 为默认版本
查看 Python 的路径,在 /usr/bin 下面。可以看到 python 链接的是 python 2.7,所以,执行 python 就相当于执行 python 2.7。
备份原来的python1
mv /usr/bin/python /usr/bin/python.bak
将 python 链接至 python3,创建pip链接:1
2ln -s /usr/python3/bin/python3 /usr/bin/python
ln -s /usr/python3/bin/pip3 /usr/bin/pip
这时,再查看 Python 的版本:1
python -VPython 3.5.2
输出的是 3.x,说明已经使用的是 python3了。
配置 yum
升级 Python 之后,由于将默认的 python 指向了 python3,yum 不能正常使用,需要编辑 yum 的配置文件:
1 | vi /usr/bin/yum |
同时修改:
1 | vi /usr/libexec/urlgrabber-ext-down |
将 #!/usr/bin/python 改为 #!/usr/bin/python2.7,保存退出即可。
版权声明:进步始于交流,收获源于分享!纯正开源之美,有趣、好玩、靠谱。。。作者:一去丶二三里 博客地址:http://blog.csdn.net/liang19890820
Python主要第三方模块和类(持续更新)
NOVEMBER 12, 2017
random模块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#random模块主要随机..
import random
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#random.random()方法主要生成0-1的随机数
print(random.random())
#0.3245447 0-1的随机数
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#random.uniform(a,b)主要是生成在a-b区间的浮点数
print(random.uniform(10,20))
#13.1025687422363 10-20的浮点数
print(random.uniform(20,10))
#19.68574558
#如果a>b 那么 b<=结果<=a
#如果a<b 那么 a<=结果<=b
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#random.randint(a,b)主要生成随即整数 a<=结果<=b 其中a必须小于等于b
print (random.randint(10, 20))
#17 10<=结果<=20
print (random.randint(20, 20))
#20 结果永远是20
#print(random.randint(20,10))会报错 a必须小于等于b
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#random.choice(sequence) 从有序类型sequence中随机选出一个值 这个类型可以是列表,元组,字符串. 注意,字典和集合不能
print(random.choice('abcd'))
#c 在字符串abcd中随机选一个
print(random.choice((1,2,3,4)))
#4 在元组(1,2,3,4)中随机选出一个值
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#random.shuffle()的函数原型为:random.shuffle(x[, random]),用于将一个列表中的元素打乱。如:
p = [1, 2, 3,4,'python']
random.shuffle(p)
print(p)
#[2, 'python', 3, 4, 1] 会改变p的值
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#random.sample(sequence, k)从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。适用于集合,字符串,列表,元组.不适用于字典 生成的只有列表, 原类型不会改变
list = (1,2,3,4,5,6,7,8,9,10)
slice = random.sample(list, 5) #从list中随机获取5个元素,作为一个片断返回
print(slice)
#[7,10,6,2,9] 随机取了5个数字 生成的只是列表
print(list)
#(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)原有序列并没有改变 元组类型也不会改变
python的内置函数(持续更新)
NOVEMBER 11, 2017
print函数
print作为python的基本输出语句,在格式化输出中与c语言有很多相似的地方,但是要比c语言强大得多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#格式化输出与c语言大差不差,只是前面在双引号里 用%进行占位,后面用%隔开,用元组进行解释
age=12
PI=3.1415926
print("age is %d pi = %.3f"%(age,PI))
#age is 12 pi = 3.142 用百分号隔开,后面是元组用于解释
print("pi = %.*f"%(4,PI))
#pi = 3.1416 动态设置保留小数位数
'''d,i 带符号的十进制整数
o 不带符号的八进制
u 不带符号的十进制
x 不带符号的十六进制(小写)
X 不带符号的十六进制(大写)
e 科学计数法表示的浮点数(小写)
E 科学计数法表示的浮点数(大写)
f,F 十进制浮点数
g 如果指数大于-4或者小于精度值则和e相同,其他情况和f相同
G 如果指数大于-4或者小于精度值则和E相同,其他情况和F相同
C 单字符(接受整数或者单字符字符串)
r 字符串(使用repr转换任意python对象)
s 字符串(使用str转换任意python对象)'''
a=1
b=2
c=3
print(a,b,c)
#1 2 3默认中间是一个空格,结尾一个换行
print(a,b,c,end='ending',sep='*')
#1*2*3ending sep可以设置元素中间隔字符 end设置结尾输出
print("format输出:a={0} b={1} c={2}".format(a,b,c))
#format输出:a=1 b=2 c=3 format输出用{0},{1}占位
print("format输出:a={2} b={1} c={2}".format(a,b,c))
#format输出:a=3 b=2 c=3 {}里面的数字是后面元组元素的序列,可以只用到部分元素,但是不能越界,注意序列从0开始
print("{0:.3f}".format(1.2345))
#1.235
count
1 | #count可以判断列表,元组,字符串含有多少个要查询的元素,注意集合,字典不能使用,他们可以用in判断是否含有某元素 |
字符串相关函数str
split:1
2
3
4
5
6
7
8
9
10#split函数能够将一个字符串根据某部分字符串分成多个部分放在列表里
a='123-456-789'
print(a.split('-'))
#['123', '456', '789']
print(a.split('-4'))
#['123', '56-789']
print(a.split('hh'))
#['123-456-789'] 如果字符串中没有该部分字符串,那么生成序列只有一个原字符串
map函数
1 | #map() 会根据提供的函数对指定序列做映射。第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表 |
isinstance()
1 | #isinstance(object,class-or-type-or-tuple)-bool |
python汇总(持续更新)
NOVEMBER 10, 2017
生成素数列:
用列表推导式生成 :1
2 >>> [p for p in range(2,100) if 0 not in[p%d for d in range(2,int(sqrt(p))+1)]]
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73,79, 83, 89, 97]
用生成器推导式生成:1
2
3
4
5
6
7
8
9
10
11from math import sqrt
def primer(n=100):
'''大于1小于等于n的素数推导式'''
a=2
while a<=n:
if 0 not in [a%d for d in range(2,int(sqrt(a)+1))]:
yield a
a+=1
a=primer(100)
list(a)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
序列解包(穿插print的用法):
1 | #序列解包 |
函数参数的解包:
1 | #函数中可变长度的参数 |
传递参数时的序列解包:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15def demo(a,b,c):
print(a+b+c)
a=(1,2,3)
demo(*a)
#6
dic={'a':1,'b':2,'c':3}
demo(*dic)
#abc
demo(*dic.items())
#('a', 1, 'b', 2, 'c', 3)
demo(*dic.values())
#6
python3链接mysql数据库
用mysqlconnector1
pip install mysql-connector