Python学习笔记
代码下载地址
链接:https://pan.baidu.com/s/1yGnpfq4ZHeKpt4V0J_PTSg
提取码:hmzs
1. Python 基础语法
1.1 基本数据类型
- 整数(int):8
- 浮点数(float):8.8
- 字符串(str):“8” “Python”
- 布尔值(bool):True False
print(type(int('8')))
print(type(str(123)))
print(type(bool(123)))
print(bool(0))
1.2 变量的定义和常用操作
- a = 123
a为变量名称,=为变量赋值,123为变量得到的值
print(100/8)
bandwidth = 100
ratio = 8
print(bandwidth/ratio)
Python编码风格指南
2. 序列
2.1 序列的概念
-
特点:成员都是有序排列,并且可以通过下标偏移量访问到它的一个或几个成员
-
字符串、列表、元组三种类型都属于序列
-
字符串:“abcd”
-
列表:[0, “abcd”]
-
元组:(“abc”, “def”)
-
思考:元组和列表的区别?
答:相同点:都是序列,可以通过索引访问,可以存储任何数据类型
不同点:写法不同,列表是可变的,元组是不可变的
-
无关知识点 :在Python单引号跟双引号字符串没有区别,只是当你的字符串内容中有单引号出现时可以用双引号将整个字符串圈起来
chinese_zodiac = '鼠牛虎兔龙蛇马羊猴鸡狗猪'
print(chinese_zodiac[0:4])
print(chinese_zodiac[-1])
2.2 字符串的定义和使用
chinese_zodiac = '猴鸡狗猪鼠牛虎兔龙蛇马羊'
year = 2022
print(year%12)
print(chinese_zodiac[year%12])
2.3 序列的基本操作
- 对象[not] in 序列
- 序列+序列
- 序列*整数
- 序列[0:整数]
chinese_zodiac = '猴鸡狗猪鼠牛虎兔龙蛇马羊'
print('狗' in chinese_zodiac)
print('狗' not in chinese_zodiac)
print(chinese_zodiac + 'abcd')
print(chinese_zodiac * 3)
2.4 元组的定义和常用操作
a = (4)
b = (5)
print(a > b)
print(a < b)
c = (1,50)
d = (1,200)
print(c > d)
print(c < d)
zodiac_name = (u'魔羯座', u'水瓶座', u'双鱼座', u'白羊座', u'金牛座', u'双子座', u'巨蟹座',
u'狮子座', u'处女座', u'天秤座', u'天蝎座', u'射手座')
zodiac_days = ((1, 20), (2, 19), (3, 21), (4, 21), (5, 21), (6, 22), (7, 23),
(8, 23), (9, 23), (10, 23), (11, 23), (12, 23))
(month, day) = (2, 15)
zodiac_day = filter(lambda x: x <= (month, day), zodiac_days)
zodiac_len = len(list(zodiac_day))
print(zodiac_name[zodiac_len])
2.5 列表的定义和常用操作
常用操作:
- append(x):向列表中插入一个元素x
- remove(x):从列表中删除元素x
a_list = ['abc', 'xyz']
a_list.append('X')
print(a_list)
a_list.remove('xyz')
print(a_list)
3. 条件与循环
3.1 条件语句
3.2 循环
-
for语句:
for 迭代变量 in 可迭代对象:
代码块
chinese_zodiac = '猴鸡狗猪鼠牛虎兔龙蛇马羊'
for cz in chinese_zodiac:
print(cz)
for i in range(3):
print(i)
for i in range(1, 3):
print(i)
for year in range(2000, 2023):
print('%s 年的生肖是 %s' %(year, chinese_zodiac[year % 12]))
-
while语句:
while 条件表达式:
代码块
-
for循环+if判断:
zodiac_name = (u'魔羯座', u'水瓶座', u'双鱼座', u'白羊座', u'金牛座', u'双子座', u'巨蟹座',
u'狮子座', u'处女座', u'天秤座', u'天蝎座', u'射手座')
zodiac_days = ((1, 20), (2, 19), (3, 21), (4, 21), (5, 21), (6, 22), (7, 23),
(8, 23), (9, 23), (10, 23), (11, 23), (12, 23))
int_month = int(input('请输入月份:'))
int_day = int(input('请输入日期:'))
for zd_num in range(len(zodiac_days)):
if zodiac_days[zd_num] >= (int_month, int_day):
print(zodiac_name[zd_num])
break
elif int_month == 12 and int_day > 23:
print(zodiac_name[0])
break
-
while循环+if判断:
zodiac_name = (u'魔羯座', u'水瓶座', u'双鱼座', u'白羊座', u'金牛座', u'双子座', u'巨蟹座',
u'狮子座', u'处女座', u'天秤座', u'天蝎座', u'射手座')
zodiac_days = ((1, 20), (2, 19), (3, 21), (4, 21), (5, 21), (6, 22), (7, 23),
(8, 23), (9, 23), (10, 23), (11, 23), (12, 23))
int_month = int(input('请输入月份:'))
int_day = int(input('请输入日期:'))
n = 0
while zodiac_days[n] < (int_month, int_day):
if int_month == 12 and int_day > 23:
break
n += 1
print(zodiac_name[n])
4. 映射与字典
-
字典:
-
列表推导式与字典推导式:
even_list = []
for i in range(1, 11):
if (i % 2) == 0:
even_list.append(i * i)
print(even_list)
even_list2 = [i * i for i in range(1, 11) if (i % 2) == 0]
print(even_list2)
zodiac_name = (u'魔羯座', u'水瓶座', u'双鱼座', u'白羊座', u'金牛座', u'双子座', u'巨蟹座',
u'狮子座', u'处女座', u'天秤座', u'天蝎座', u'射手座')
z_dict = {}
for i in zodiac_name:
z_dict[i] = 0
print(z_dict)
z_dict2 = {k: 0 for k in zodiac_name}
print(z_dict2)
5. 文件和输入输出
5.1 文件的内建函数
- 定义:python自带的函数,不需要额外去安装
- 基本的函数:
- open():打开文件
- read():输入
- readline():输入一行
- seek():文件内移动
- write():输出
- close():关闭文件
- 注意:
- 在打开文件之后一定要对文件进行关闭,否则电脑突然关机的话你写入的信息就会丢失。
5.2 文件的常用操作
-
读取一行:readline()
-
读取多行:readlines()
得到一个列表,列表中每一个元素都是一行的内容
-
读取整个内容:read()
直接得到整个文章的内容,用字符串的形式去存储
-
读取固定数字符:read(x)
x代表读取的字符数量
-
移动文件读取指针:
- 单个参数时:
seek(x)
代表移动到文章第几个字符处,从0开始 - 两个参数时:
seek(a, b)
第一个参数代表偏移位置 第二个参数0表示从文件开头偏移1表示从当前位置偏移2表示从文件结尾
-
例子:
file6 = open('name.txt')
print('当前文件指针的位置 %s' % (file6.tell()))
print('当前读取到了一个字符,字符的内容是 %s' % file6.read(1))
print('当前文件指针的位置 %s' % (file6.tell()))
file6.seek(2, 0)
print('我们进行了seek操作')
print('文件指针回到了位置 %s' % (file6.tell()))
print('当前读取到了一个字符,字符的内容是 %s' % file6.read(1))
print('当前文件指针的位置 %s' % (file6.tell()))
file6.close()
6. 错误和异常
-
异常:
-
产生:出现错误时采用正常控制流以外的动作
-
异常处理的一般流程:
- 检测到错误,引发异常
- 对异常进行捕获操作
-
异常处理代码格式:
try:
<监控异常>
except Exception[,reason]:
<异常处理代码>
finally:
<无论异常是否发生都执行>
-
简单试验:
try:
raise NameError('helloError')
except NameError:
print('my Custom error')
7. 函数
-
定义:对程序逻辑进行结构化的一种编程方法
-
定义格式:
def 函数名称():
代码
return 需要返回的内容
-
函数的调用:函数名称()
-
函数传参时使用指定关键字:
print('abc', end='\n')
def func(a, b, c):
print('a = %s' %a)
print('b = %s' %b)
print('c = %s' %c)
func(1, 2, 3)
func(1, c = 2, b = 3)
7.1 函数的可变长参数
def howlong(first, *other):
print(1 + len(other))
howlong(1, 2, 3)
7.2 函数的变量作用域
var1 = 123
def func():
var1 = 456
print(var1)
func()
print(var1)
7.3 函数的迭代器与生成器
- iter():用来生成迭代器
- next():返回迭代器的下一个项目
list1 = [1, 2, 3]
it = iter(list1)
print(next(it))
print(next(it))
print(next(it))
print(next(it))
list2 = ['a', 'b', 'c']
for i in iter(list2):
print(i)
- 生成器:使用了yield的函数称为生成器,生成器是迭代器的一种。调用一个生成器函数,返回一个迭代器对象。
def frange(start, stop, step):
x = start
while x < stop:
yield x
x += step
for i in frange(10, 20, 0.5):
print(i)
7.4 Lambda表达式
- 使用:在我们仅仅使用函数进行简单计算的时候使用。省去了写return和定义函数名称的过程。
def add(x, y):
return x + y
lambda x,y: x + y
7.5 Python内建函数
-
filter(func, iterable):将符合指定函数的项给选出来
a = [1, 2, 3, 4, 5, 6, 7]
list(filter(lambda x:x>2, a))
-
map():对每个元素依次进行操作变变换
a = [1, 2, 3]
b = [4, 5, 6]
list(map(lambda x:x+1, a))
list(map(lambda x,y:x+y, a, b))
-
reduce():序列的所有项和初始值依次按照函数做运算注意:reduce虽然是内建函数,但是得用from functools import reduce
导入
reduce(lambda x,y: x+y, [2,3,4], 1)
-
zip():可以使两个元组纵向合并。可以实现字典的key、value对调
a = (1, 2, 3)
b = (4, 5, 6)
tuple(zip(a, b))
for i in zip(a, b):
print(i)
dicta = {'a':'aaa', 'b':'bbb'}
dictb = dict(zip(dicta.values(), dicta.keys()))
dictb
-
补充:
7.6 闭包
-
定义:嵌套的函数,且当外部函数的参数被内部函数给引用的情况下我们称其为闭包。
-
小示例:
def counter(FIRST=0):
cnt = [FIRST]
def add_one():
cnt[0] += 1
return cnt[0]
return add_one
num1 = counter(5)
num2 = counter(10)
print(num1())
print(num1())
print(num2())
print(num2())
运行结果:
6
7
11
12
发现:
互不影响,这也是闭包的好处。
def a_line(a, b):
def arg_y(x):
return a * x + b
return arg_y
line1 = a_line(3, 5)
line2 = a_line(10, 5)
print(line1(5))
print(line2(5))
'''
闭包优雅写法
def a_line(a, b):
return lambda x:a*x+b
'''
- 好处:比传统的实现方式传参少,定义函数时只需要传a、b两个参数,使用线段求y时只用传x一个参数。
7.7 装饰器
-
定义与闭包类似,只不过它传递的参数是一个函数,使用方法经过不断演化后得到了简化。
-
示例:
import time
def I_sleep():
time.sleep(3)
start_time = time.time()
I_sleep()
stop_time = time.time()
print("程序运行了%s" %(stop_time-start_time))
def timer(func):
def wrapper():
start_time = time.time()
func()
stop_time = time.time()
print("程序运行了%s" %(stop_time-start_time))
return wrapper
@timer
def I_sleep2():
time.sleep(3)
I_sleep2()
-
带参数的装饰器:
def out(func):
def inner(a,b):
print('start')
func(a,b)
print('stop')
return inner
@out
def add(a,b):
print(a + b)
add(7,3)
-
针对不同函数装饰器做适应:
def new(argv):
def out(func):
def inner(a,b):
print('start %s %s' %(argv, func.__name__))
func(a,b)
print('stop')
return inner
return out
@new('add_module')
def add(a,b):
print(a + b)
@new('sub_module')
def sub(a,b):
print(a - b)
add(3, 5)
sub(5, 3)
-
好处:
- 调用函数时不用在上面下面去编写重复的代码,可以将这些代码放在装饰器里面。
- 装饰器更易于复用
7.8 自定义上下文管理器
先来看看一般打开文件的方法
fd = open('name.txt')
try:
for line in fd:
print(line)
finally:
fd.close()
上面这种方法是不优雅的
下面我们使用with
上下文管理器的方法去精简
with open('name.txt') as f:
for line in f:
print(line)
通过这种方法省去了我们写finally,因为在出现异常的时候,它会自动帮我们做关闭的操作。
8. 模块
在代码量变得相当大之后,将需要重复使用的有组织的代码段放在一起组成一个文件,这个文件就是模块。可以附加到现有的程序中。
9. 面向对象编程
9.1 类与实例
user1 = {'name':'tom','hp':100}
user2 = {'name':'jerry','hp':80}
def print_role(rolename):
print('name is %s,hp is %s' %(rolename['name'], rolename['hp']))
print_role(user1)
print_role(user2)
class Player():
def __init__(self, name, hp):
self.name = name
self.hp = hp
def print_role(self):
print('name is %s,hp is %s' %(self.name, self.hp))
user1 = Player('Tom', 100)
user2 = Player('Jerry', 80)
user1.print_role()
user2.print_role()
9.2 增加类的属性和方法
class Player():
def __init__(self, name, hp, occu):
self.__name = name
self.hp = hp
self.occu = occu
def print_role(self):
print('name is %s,hp is %s,occupation is %s' %(self.__name, self.hp, self.occu))
def updateName(self, newname):
self.__name = newname
user1 = Player('Tom', 100, 'war')
user2 = Player('Jerry', 80, 'master')
user1.print_role()
user2.print_role()
user1.updateName('wilson')
user1.print_role()
其中name默认是公有成员,也可以通过实例.name的方式去访问和更改。
如果想使得name不能使用.name 的方式去访问和更改,可以在其类中使用__name
。
9.3 类的继承
class Monster():
pass
class Animals(Monster):
pass
class Boss(Monster):
pass
class Monster():
def __init__(self, hp = 100):
self.hp = hp
def run(self):
print('移动到某个位置')
def whoami(self):
print('我是怪物父类')
class Animals(Monster):
def __init__(self, hp = 10):
super().__init__(hp)
class Boss(Monster):
def __init__(self, hp=800):
super().__init__(hp)
def whoami(self):
print('我是Boss')
a1 = Monster(200)
a1.run()
print(a1.hp)
a2 = Animals(100)
a2.run()
print(a2.hp)
a3 = Boss(1000)
a3.whoami()
print('a1的类型 %s' %type(a1))
print('a2的类型 %s' %type(a2))
print('a3的类型 %s' %type(a3))
print(isinstance(a2, Monster))
9.4 自定义with语句
class Testwith():
def __enter__(self):
print('run')
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit')
with Testwith():
print('test is running')
运行结果:
run
test is running
exit
class Testwith():
def __enter__(self):
print('run')
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_tb is None:
print('正常结束')
else:
print('has error %s' %exc_tb)
with Testwith():
print('test is running')
raise NameError('testNameError')
10. 多线程编程
-
定义:同时处理多个请求的方法
-
线程的简单使用:
import threading
import time
from threading import current_thread
def myThread(arg1, arg2):
time.sleep(1)
print('%s %s' %(arg1, arg2))
for i in range(1, 6, 1):
t1 = threading.Thread(target=myThread,args=(i, i + 1))
t1.start()
-
让主线程等待其他线程结束之后再结束
import threading
from threading import current_thread
class Mythread(threading.Thread):
def run(self):
print(current_thread().getName(), 'start')
print('run')
print(current_thread().getName(), 'stop')
t1 = Mythread()
t1.start()
t1.join()
print(current_thread().getName(), 'end')
-
生产者和消费者:
from threading import Thread,current_thread
import time
import random
from queue import Queue
queue = Queue(5)
class ProducerThread(Thread):
def run(self):
name = current_thread().getName()
nums = range(100)
global queue
while True:
num = random.choice(nums)
queue.put(num)
print('生产者 %s 生产了数据 %s' %(name, num))
t = random.randint(1, 3)
time.sleep(t)
print('生产者 %s 睡眠了 %s 秒' %(name, t))
class ConsumerThread(Thread):
def run(self):
name = current_thread().getName()
global queue
while True:
num = queue.get()
queue.task_done()
print('消费者 %s 消耗了数据 %s' %(name, num))
t = random.randint(1, 5)
time.sleep(t)
print('消费者 %s 睡眠了 %s 秒' %(name, t))
p1 = ProducerThread(name = 'p1')
p1.start()
p2 = ProducerThread(name = 'p2')
p2.start()
p3 = ProducerThread(name = 'p3')
p3.start()
c1 = ConsumerThread(name = 'c1')
c1.start()
c2 = ConsumerThread(name = 'c2')
c2.start()
11. 标准库
- 定义:安装python后自带的库
- 目前比较广泛的模块:
- 文字处理的re
- 日期类型的time、datetime
- 数字和数学类型的math、random
- 文件和目录访问的pathlib、os.path
- 数据压缩和归档的tarfile
- 通用操作系统的os、logging、argparse
- 多线程的threading、queue
- Internet数据处理的base64、json、urllib
- 结构化标记处理工具的html、xml
- 开发工具的unitest
- 调试工具的timeit
- 软件包发布的venv
- 运行服务的__main__
11.1 正则表达式库re的使用
-
导入import re
-
单个字符的匹配:
import re
p = re.compile('a')
print(p.match('a'))
print(p.match('b'))
运行结果:
<re.Match object; span=(0, 1), match='a'>
None
-
正则表达式元字符:
.
匹配任意一个字符除换行符\d
匹配任意一个数字- 更多
-
匹配日期:
p = re.compile(r'(\d+)-(\d+)-(\d+)')
print(p.match('2022-05-05').group())
print(p.match('2022-05-07').group(1))
print(p.match('2022-05-07').groups())
year,month,day = ('2022', '05', '07')
-
正则表达式match与search的区别
- match要求原字符和输入字符完全匹配。即当第一个字符与原字符不匹配时便返回匹配失败。
- search不会,它会沿输入字符继续向后进行匹配。
- match经常是用于完全匹配之后进行分组。
-
正则表达式库替换函数sub
-
sub(str1, str2, str3):
- str1:匹配的规则
- str2:匹配到的字符串要替换成的内容
- str3:将要替换的字符串
-
使用:
phone = '123-456-789 # 这是一个电话号码'
p = re.sub(r'#.*$', '', phone)
print(p)
p2 = re.sub(r'\D','',p)
print(p2)
运行结果:
123-456-789
123456789
-
补充:
- search只能匹配一次,想要匹配多次要用findall
11.2 日期与时间函数库
-
时间库:
-
以当前时间为准,计算指定偏移后的时间
import datetime
print(datetime.datetime.now())
newtime = datetime.timedelta(minutes = 10)
print(datetime.datetime.now() + newtime)
one_day = datetime.datetime(2008,5,27)
new_date = datetime.timedelta(days = 10)
print(one_day + new_date)
11.2 数学相关库
-
math
-
random
- randint():返回指定区间的随机数
- choice(obj):从对象中任选一值
import random
print(random.randint(1, 5))
print(random.choice([1, 2, 'a', 'b']))
11.3 文件与目录操作库
12. 机器学习库
12.1 Numpy库
-
用途:主要用于高性能科学计算和数据分析,是常用的高级数据分析库的基础包。
-
简单使用:
import numpy as np
arr1 = np.array([2, 3, 4])
print(arr1)
print(arr1.dtype)
arr2 = np.array([2.1, 3.1, 4.1])
print(arr2)
print(arr2.dtype)
print(arr1 + arr2)
print(arr2 * 10)
data = [[1,2,3], [4,5,6]]
arr3 = np.array(data)
print(arr3)
print(arr3.dtype)
print(type(arr3))
print(np.zeros(10))
print(np.zeros((3, 5)))
print(np.ones((4, 6)))
print(np.empty((2,3,2)))
arr4 = np.arange(10)
print(arr4[5])
print(arr4[5:8])
arr4[5:8] = 0
print(arr4)
arr_slice = arr4[5:8]
arr_slice[:] = 1
print(arr4)
arr_slice = arr4[5:8].copy()
arr_slice[:] = 0
print(arr4)
print(arr_slice)
arr5 = np.array(['a', 'b', 'c', 'd'])
print(arr5[1])
12.2 Pandas库
-
好处(相比于Numpy):
- 自动帮你将数据对齐显示
- 可以灵活的处理缺失的数据、
- 还可以实现像类似sql语句一样的连接操作
-
特点:
-
简单使用:
import pandas as pd
obj = pd.Series([4, 5, 6, -7])
print(obj)
print(obj.index)
print(obj.values)
obj2 = pd.Series([4, 5, 6, 3], index = {'a', 'b', 'd', 'c'})
print(obj2)
obj2['c'] = 6
print(obj2)
print('c' in obj2)
print('f' in obj2)
sdata = {'beijing' : 35000, 'shanghai' : 70000, 'guangzhou' : 16000, 'shenzhen' : 5000}
obj3 = pd.Series(sdata)
print(obj3)
obj3.index = ['bj', 'sh', 'gz', 'sz']
print(obj3)
data = {'city' : ['shanghai', 'guangzhou', 'beijing', 'shenzhen'],
'year' : [2016, 2017, 2018, 2019],
'pop' : [1.5, 1.8, 1.3, 2.0]}
frame = pd.DataFrame(data)
print(frame)
frame2 = pd.DataFrame(data, columns = ['year', 'city', 'pop'])
print(frame2)
print(frame2['city'])
print(frame2.year)
frame2['cap'] = frame2.city == 'beijing'
print(frame2)
pop = { 'beijing' : {2008:1.5, 2009:2.0},
'shanghai' : {2008:2.0, 2009:3.6}
}
frame3 = pd.DataFrame(pop)
print(frame3)
print(frame3.T)
obj4 = pd.Series([4.5, 7.2, -5.3, 3.6], index = ['b', 'd', 'c', 'a'])
obj5 = obj4.reindex(['a', 'b', 'c', 'd', 'e'])
print(obj5)
obj6 = obj4.reindex(['a', 'b', 'c', 'd', 'e'], fill_value = 0)
print(obj6)
obj7 = pd.Series(['blue', 'yellow', 'pink'], index = [0, 2, 4])
print(obj7.reindex(range(6)))
print(obj7.reindex(range(6), method = 'ffill'))
from numpy import nan as NA
data = pd.Series([1, NA, 2])
print(data.dropna())
data = pd.DataFrame([[1., 6.5, 3], [1., NA, NA], [NA, NA, NA]])
data[4] = NA
print(data)
print(data.dropna())
print(data.dropna(how = 'all'))
print(data.dropna(axis = 1, how = 'all'))
data.fillna(0)
data.fillna(0, inplace = True)
print(data)
import numpy as np
data3 = pd.Series(np.random.randn(10),
index = [['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'd', 'd'],
[1, 2, 3, 1, 2, 3, 1, 2, 2, 3]])
print(data3)
print(data3.unstack())
print(data3.unstack().stack())
12.3 Matplotlib库
-
用途:绘图
-
简单使用:
import matplotlib.pyplot as plt
plt.plot([1, 3, 5], [4, 8, 10])
plt.show()
import numpy as np
x = np.linspace(-np.pi, np.pi, 100)
print(x)
plt.plot(x, np.sin(x))
plt.show()
x = np.linspace(-np.pi * 2, np.pi * 2, 100)
plt.figure(1, dpi = 50)
for i in range(1, 5):
plt.plot(x, np.sin(x / i))
plt.show()
plt.figure(1, dpi = 50)
data = [1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 6, 4]
plt.hist(data)
plt.show()
x = np.arange(1, 10)
y = x
fig = plt.figure()
plt.scatter(x, y, c = 'r', marker = 'o')
plt.show()
import pandas as pd
iris = pd.read_csv('./iris_training.csv')
print(iris.head())
iris.plot(kind = 'scatter', x = '120', y = '4')
plt.show()
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
iris = pd.read_csv('./iris_training.csv')
sns.set(style = 'white', color_codes = True)
sns.FacetGrid(iris, hue = 'virginica', size = 5).map(plt.scatter, '120', '4').add_legend()
sns.FacetGrid(iris, hue = 'virginica', size = 5).map(plt.scatter, 'setosa', 'versicolor').add_legend()
13. 爬虫
13.1 网页数据采集与urllib库
13.2 requests库的基本使用
-
使用:import requests
-
get请求:
import requests
url = 'http://httpbin.org/get'
data = {'key': 'value'}
response = requests.get(url, data)
print(response.text)
-
post请求:
import requests
url = 'http://httpbin.org/post'
data = {'key' : 'value'}
response = requests.post(url, data)
print(response.text)
-
爬虫小栗子:
import requests
import re
content = requests.get('http://www.mnw.cn/news/china/')
content.encoding = 'utf8'
pattern = re.compile(r'<div class="item noimg.*?<a.*?>(.*?)</a>', re.S)
results = re.findall(pattern, content.text)
for result in results:
print(re.sub('\s', '', result))
-
re.S的作用:
不使用re.S时,则只在每一行内进行匹配,如果存在一行没有,就换下一行重新开始,使用re.S参数以后,正则表达式会将这个字符串看做整体,在整体中进行匹配 。
13.3 BeautifulSoup库的基本使用
-
作用:处理请求得到的html文本,一般情况下比使用正则更容易处理得到想要内容
-
简单使用:
html_doc = """
<html><head><title>网页标题</title></head><body>
<p class= "item2">这是一个段落</p>
<p class="item" id="first">这是第二个段落</p>
<a href="http://baidu.com">百度一下</a>
</body></html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'lxml')
print(soup.prettify())
print(soup.title)
print(soup.title.string)
print(soup.p)
print(soup.p.string)
print(soup.p['class'])
print(soup.find_all('p'))
print(soup.find(id='first'))
for link in soup.find_all('a'):
print(link.get('href'))
-
爬取百度新闻:
from bs4 import BeautifulSoup
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER"
}
url = "http://news.baidu.com"
def craw2(url):
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, "lxml")
for title_href in soup.find_all("div", class_="mod-tab-pane active"):
for title in title_href.find_all("a"):
title_url=title.get("href")
print(title.text,title_url)
craw2(url)
-
爬取图片网站的图片:
import os
import shutil
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36",
}
url = "http://www.netbian.com/"
def download_jpg(image_url, image_localpath):
response = requests.get(image_url, stream = True)
if response.status_code == 200:
with open(image_localpath, 'wb') as f:
response.raw.deconde_content = True
shutil.copyfileobj(response.raw, f)
def craw3(url):
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'lxml')
for div in soup.find_all('div', class_="list"):
for img in div.find_all('img'):
imgurl = img.get('src')
dir = os.path.abspath('./爬取的图片/')
filename = os.path.basename(imgurl)
imgpath = os.path.join(dir, filename)
print('开始下载 %s' % imgurl)
download_jpg(imgurl, imgpath)
craw3(url)
14. 设计合理的代码结构
- 如果使用的功能不需要调用库的话,尽量不要去调用库
- 在编写大型程序时,优先把逻辑编写出来,具体实现封装到函数当中
- 程序带有的功能建议单独写到一个模块中
知识点
- 序列包含列表、元组、字符串,sort() 函数是列表的方法。
- 元组和列表的删除都可以使用del()关键字
- 语法错误跟finally中遇到文件打开失败都会引发异常
- 不可变类型可以作为字典的key
- python中类的父类可以有多个
- queue库是线程安全的
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)