引用:【【全748集】这绝对是2024最全最细的Python全套教学视频,七天看完编程技术猛涨!别再走弯路了,从零基础小白到Python全栈这一套就够了!-哔哩哔哩】 https://b23.tv/lHPI3XV
语法基础
Python解释器与pycharm编辑器安装
- 定义:Python解释器负责将Python代码转换为计算机能理解的机器语言;PyCharm是一款功能强大的Python集成开发环境(IDE),能提高开发效率。
- 例题:无实际例题,主要是实践操作,学会下载、安装Python解释器和PyCharm编辑器,并进行基本配置。
- 代码:无实际代码,是安装和配置过程。
首个程序编写、处理BUG
- 定义:编写Python代码实现简单功能,如输出“Hello, World!”,并学会排查和解决编写过程中出现的错误。
- 例题:编写程序输出“Hello, Python”,若出现语法错误,分析错误原因并改正。
- 代码:
print("Hello, Python")
Debug、注释及输出函数学习
- 定义:Debug是调试代码的过程,找到并修复错误;注释用于解释代码功能,提高代码可读性;输出函数(如 print )用于将信息显示在控制台。
- 例题:编写一个计算两个数之和的程序,使用Debug查看变量值变化,添加注释说明代码功能,用 print 输出结果。
- 代码:
# 计算两个数之和
a = 3
b = 5
# 计算结果
result = a + b
print("两数之和为:", result)
变量与标识符认知
- 定义:变量是存储数据的容器,标识符是给变量、函数、类等命名的名称,需遵循一定规则。
- 例题:定义不同类型的变量(整数、字符串、浮点数),并判断标识符命名是否正确。
- 代码:
# 定义整数变量
age = 20
# 定义字符串变量
name = "Tom"
# 定义浮点数变量
height = 1.75
数值类型、字符串及格式化输出
- 定义:数值类型包括整数( int )、浮点数( float )等;字符串是字符序列;格式化输出用于按指定格式显示变量值。
- 例题:进行数值运算,拼接字符串,使用格式化输出显示个人信息。
- 代码:
# 数值运算
num1 = 5
num2 = 3
print(num1 + num2)
# 字符串拼接
str1 = "Hello"
str2 = "World"
print(str1 + ", " + str2)
# 格式化输出
name = "Alice"
age = 25
print("我的名字是%s,年龄是%d" % (name, age))
运算符学习
- 定义:包括算术运算符(如 + 、 - 、 * 、 / )、比较运算符(如 > 、 < 、 == )、逻辑运算符(如 and 、 or 、 not )等,用于进行各种运算和条件判断。
- 例题:使用不同运算符进行运算,并判断结果。
- 代码:
# 算术运算符
print(5 + 3)
print(5 - 3)
print(5 * 3)
print(5 / 3)
# 比较运算符
print(5 > 3)
print(5 < 3)
print(5 == 3)
# 逻辑运算符
print((5 > 3) and (5 < 10))
print((5 > 3) or (5 < 1))
print(not (5 > 3))
if判断、比较与逻辑运算符
- 定义: if 语句用于根据条件执行不同代码块,结合比较和逻辑运算符进行条件判断。
- 例题:判断一个数是否大于10,多个条件判断一个数是否在某个范围内。
- 代码:
num = 15
if num > 10:
print(num, "大于10")
age = 22
if age >= 18 and age < 30:
print("年龄在18到30之间")
if_else、if_elif及if嵌套
- 定义: if_else 在条件为真和假时执行不同代码块; if_elif 用于多个条件的判断; if 嵌套是在一个 if 语句中再包含其他 if 语句。
- 例题:根据成绩判断等级(A、B、C等),嵌套判断一个数是否在不同区间。
- 代码:
score = 85
if score >= 90:
print("等级为A")
elif score >= 80:
print("等级为B")
else:
print("等级为C")
num = 12
if num > 0:
if num < 10:
print(num, "在0到10之间")
else:
print(num, "大于10")
else:
print(num, "小于等于0")
循环语句,while循环
- 定义: while 循环在条件为真时重复执行代码块。
- 例题:使用 while 循环计算1到10的累加和。
- 代码:
sum_num = 0
i = 1
while i <= 10:
sum_num += i
i += 1
print("1到10的累加和为:", sum_num)
for循环、break与continue
- 定义: for 循环用于遍历可迭代对象; break 用于跳出循环; continue 用于跳过本次循环的剩余代码,继续下一次循环。
- 例题:使用 for 循环遍历列表,遇到特定元素时使用 break 和 continue 。
- 代码:
nums = [1, 2, 3, 4, 5]
for num in nums:
if num == 3:
break
print(num)
for num in nums:
if num == 3:
continue
print(num)
字符串编码及常见操作
- 定义:字符串编码是将字符转换为字节序列的方式;常见操作包括字符串拼接、分割、查找、替换等。
- 例题:对字符串进行编码和解码,进行字符串操作。
- 代码:
s = "你好"
# 编码
encoded_s = s.encode('utf - 8')
print(encoded_s)
# 解码
decoded_s = encoded_s.decode('utf - 8')
print(decoded_s)
# 字符串操作
s = "hello world"
print(s.split())
print(s.find('world'))
print(s.replace('world', 'python'))
列表及其相关操作
- 定义:列表是有序的可变数据集合,可包含不同类型元素,支持增删改查等操作。
- 例题:创建列表,添加、删除元素,修改元素值,查找元素。
- 代码:
fruits = ["apple", "banana", "cherry"]
# 添加元素
fruits.append("orange")
# 删除元素
fruits.remove("banana")
# 修改元素
fruits[0] = "grape"
# 查找元素
if "cherry" in fruits:
print("列表中包含cherry")
元组、字典常见操作
- 定义:元组是有序的不可变数据集合;字典是键值对的无序集合,通过键来访问值。
- 例题:创建元组和字典,进行字典的增删改查操作。
- 代码:
# 元组
my_tuple = (1, 2, 3)
print(my_tuple)
# 字典
my_dict = {"name": "John", "age": 30}
# 添加键值对
my_dict["city"] = "New York"
# 修改值
my_dict["age"] = 31
# 删除键值对
del my_dict["city"]
# 查找值
print(my_dict.get("name"))
集合操作、交集与并集
- 定义:集合是无序的不重复元素集合,可进行交集、并集、差集等操作。
- 例题:创建集合,计算两个集合的交集和并集。
- 代码:
set1 = {1, 2, 3}
set2 = {3, 4, 5}
# 交集
print(set1.intersection(set2))
# 并集
print(set1.union(set2))
类型转换
- 定义:将一种数据类型转换为另一种数据类型,如将字符串转换为整数,整数转换为浮点数等。
- 例题:进行不同类型之间的转换。
- 代码:
# 字符串转整数
num_str = "123"
num_int = int(num_str)
print(num_int)
# 整数转浮点数
num_float = float(num_int)
print(num_float)
深浅拷贝、可变与不可变类型
- 定义:浅拷贝是复制对象的引用,深拷贝是递归复制对象及其子对象;可变类型(如列表、字典)的值可以修改,不可变类型(如元组、字符串)的值不可修改。
- 例题:对列表进行深浅拷贝,并观察修改时的不同结果,判断数据类型的可变性。
- 代码:
import copy
original_list = [1, 2, [3, 4]]
# 浅拷贝
shallow_copy = copy.copy(original_list)
# 深拷贝
deep_copy = copy.deepcopy(original_list)
original_list[2][0] = 5
print(shallow_copy)
print(deep_copy)
# 判断可变性
s = "hello"
try:
s[0] = 'H'
except TypeError:
print("字符串是不可变类型")
l = [1, 2, 3]
l[0] = 0
print("列表是可变类型", l)
函数定义、调用及返回值
- 定义:函数是一段可重复使用的代码块,通过 def 关键字定义,调用函数可执行其代码,函数可以返回值。
- 例题:定义一个计算两个数乘积的函数,调用函数并获取返回值。
- 代码:
def multiply(a, b):
return a * b
result = multiply(3, 4)
print("乘积为:", result)
函数参数、函数嵌套
- 定义:函数参数分为位置参数、默认参数、关键字参数等;函数嵌套是在一个函数内部定义另一个函数。
- 例题:定义带有不同参数类型的函数,定义并调用嵌套函数。
- 代码:
# 位置参数
def add(a, b):
return a + b
# 默认参数
def power(x, n=2):
return x ** n
# 关键字参数
def greet(name, message="Hello"):
return message + ", " + name
# 函数嵌套
def outer():
def inner():
print("这是内部函数")
inner()
outer()
作用域与匿名函数
- 定义:作用域是变量的有效范围,包括全局作用域和局部作用域;匿名函数是没有名字的函数,使用 lambda 关键字定义。
- 例题:演示变量在不同作用域的访问情况,使用匿名函数进行简单计算。
- 代码:
global_var = 10
def test():
local_var = 5
print("局部变量:", local_var)
print("全局变量:", global_var)
test()
# 匿名函数
add = lambda a, b: a + b
print("匿名函数计算结果:", add(3, 4))
内置函数与拆包
- 定义:内置函数是Python预先定义好的函数,可直接使用;拆包是将可迭代对象(如列表、元组)解包为多个变量。
- 例题:使用内置函数(如 sum 、 max ),对列表和元组进行拆包。
- 代码:
nums = [1, 2, 3, 4, 5]
# 内置函数
print("列表元素之和:", sum(nums))
print("列表中的最大值:", max(nums))
# 拆包
a, b, c = (1, 2, 3)
print(a, b, c)
x, *y = [1, 2, 3, 4]
print(x)
print(y)
异常种类、捕获与自定义异常
- 定义:异常是程序执行过程中出现的错误,Python有多种内置异常;捕获异常可以防止程序崩溃,自定义异常可满足特定业务需求。
- 例题:捕获常见异常(如 ZeroDivisionError 、 IndexError ),定义并抛出自定义异常。
- 代码:
try:
result = 10 / 0
except ZeroDivisionError:
print("除数不能为0")
try:
nums = [1, 2, 3]
print(nums[3])
except IndexError:
print("索引超出范围")
# 自定义异常
class MyError(Exception):
pass
try:
raise MyError("这是自定义异常")
except MyError as e:
print(e)
模块知识、导入方式及内置变量
- 定义:模块是包含Python代码的文件,可将相关功能封装在模块中;导入模块可以使用模块中的函数、类等;内置变量(如 __name__ )有特殊用途。
- 例题:创建模块文件,使用不同导入方式导入模块并使用其中的函数,查看 __name__ 变量的值。
- 代码:
假设创建 mymodule.py 文件,内容如下:
def add(a, b):
return a + b
在主程序中:
# 导入模块
import mymodule
result = mymodule.add(3, 4)
print(result)
# 从模块导入函数
from mymodule import add
result = add(5, 6)
print(result)
# 查看__name__变量
if __name__ == "__main__":
print("这是主程序")
包的认识、 __init__.py 文件与 __all__ 变量
- 定义:包是一个包含多个模块的目录, __init__.py 文件用于标识该目录是一个包, __all__ 变量用于控制 from package import * 时导入的模块。
- 例题:创建包结构,编写 __init__.py 文件,设置 __all__ 变量并进行模块导入。
- 代码:
假设创建包 mypackage ,目录结构如下:
plaintext
mypackage/
__init__.py
module1.py
module2.py
__init__.py 文件内容:
__all__ = ["module1"]
module1.py 文件内容:
def func1():
print("这是module1中的func1")
在主程序中:
from mypackage import *
module1.func1()
递归函数及斐波那契数列实现
- 定义:递归函数是在函数内部调用自身的函数;斐波那契数列是一个数列,从第三项开始,每一项都等于前两项之和。
- 例题:使用递归函数计算阶乘,使用递归和非递归方法实现斐波那契数列。
- 代码:
# 递归计算阶乘
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
print("5的阶乘为:", factorial(5))
# 递归实现斐波那契数列
def fibonacci_recursive(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)
# 非递归实现斐波那契数列
def fibonacci_non_recursive(n):
if n == 0:
return 0
elif n == 1:
return 1
a, b = 0, 1
for i in range(2, n + 1):
a, b = b, a + b
return b
print("第10个斐波那契数(递归):", fibonacci_recursive(10))
print("第10个斐波那契数(非递归):", fibonacci_non_recursive(10))
语法进阶
面向对象基础、类与对象、实例方法
- 定义:类是对象的模板,定义了对象的属性和方法;对象是类的实例;实例方法是定义在类中,通过对象调用的方法,它可以访问和修改对象的属性。
- 例题:创建一个简单的 Person 类,包含姓名和年龄属性,以及一个介绍自己的实例方法。
- 代码:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
return f"我叫{self.name},今年{self.age}岁。"
person = Person("Alice", 25)
print(person.introduce())
面向对象回顾、实例属性
- 定义:回顾面向对象编程的概念,实例属性是每个对象独有的数据,通过对象访问和修改。
- 例题:创建多个 Person 类的对象,分别设置和访问它们的实例属性。
- 代码:
person1 = Person("Bob", 30)
person2 = Person("Charlie", 22)
print(person1.name)
print(person2.age)
person1.age = 31
print(person1.age)
构造函数、析构函数
- 定义:构造函数( __init__ 方法)在创建对象时自动调用,用于初始化对象的属性;析构函数( __del__ 方法)在对象被销毁时自动调用,可用于执行清理操作。
- 例题:在 Person 类中添加析构函数,观察对象生命周期。
- 代码:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
print(f"{self.name}对象被创建")
def __del__(self):
print(f"{self.name}对象被销毁")
def introduce(self):
return f"我叫{self.name},今年{self.age}岁。"
person = Person("David", 28)
del person
封装:隐藏与私有属性
- 定义:封装是将对象的属性和方法隐藏起来,通过公共接口进行访问和操作,以保护数据的安全性和完整性。在Python中,通过在属性名前加双下划线( __ )来实现私有属性。
- 例题:在 Person 类中添加私有属性,并提供公共方法来访问和修改它。
- 代码:
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
def get_age(self):
return self.__age
def set_age(self, new_age):
if new_age > 0:
self.__age = new_age
person = Person("Eve", 23)
print(person.get_age())
person.set_age(24)
print(person.get_age())
单继承与方法重写
- 定义:单继承是指一个类只继承一个父类的属性和方法;方法重写是在子类中重新定义父类的方法,以实现不同的行为。
- 例题:创建一个父类 Animal 和一个子类 Dog ,子类重写父类的 make_sound 方法。
- 代码:
class Animal:
def make_sound(self):
return "通用的动物叫声"
class Dog(Animal):
def make_sound(self):
return "汪汪汪"
animal = Animal()
dog = Dog()
print(animal.make_sound())
print(dog.make_sound())
新式类写法、多继承
- 定义:新式类是Python 2.2引入的概念,继承自 object 类,具有一些新的特性;多继承是一个类可以继承多个父类的属性和方法。
- 例题:创建多个父类和一个多继承的子类,演示多继承的使用。
- 代码:
class A:
def method_a(self):
return "这是A类的方法"
class B:
def method_b(self):
return "这是B类的方法"
class C(A, B):
pass
c = C()
print(c.method_a())
print(c.method_b())
多态、静态与类方法
- 定义:多态是指同一个方法可以根据对象的不同类型而表现出不同的行为;静态方法是属于类而不属于对象的方法,通过 @staticmethod 装饰器定义;类方法是通过 @classmethod 装饰器定义,第一个参数是类本身(通常用 cls 表示)。
- 例题:在不同类中实现相同方法体现多态,定义并调用静态方法和类方法。
- 代码:
class Shape:
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
shapes = [Rectangle(4, 5), Circle(3)]
for shape in shapes:
print(shape.area())
class MyClass:
@staticmethod
def static_method():
return "这是静态方法"
@classmethod
def class_method(cls):
return "这是类方法,类名为:" + cls.__name__
print(MyClass.static_method())
print(MyClass.class_method())
单例模式、魔术方法(一)
- 定义:单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点;魔术方法是Python中具有特殊名称的方法,以双下划线开头和结尾,如 __new__ 、 __init__ 等,在特定情况下自动调用。
- 例题:使用魔术方法 __new__ 实现单例模式。
- 代码:
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2)
单例模式、魔术方法(二)
- 定义:继续深入学习单例模式的不同实现方式,以及其他魔术方法(如 __str__ 、 __repr__ )的使用。 __str__ 方法用于返回对象的字符串表示,通常用于用户友好的输出; __repr__ 方法用于返回对象的“官方”字符串表示,通常用于调试和开发。
- 例题:在类中实现 __str__ 和 __repr__ 方法,观察其效果。
- 代码:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"Point({self.x}, {self.y})"
def __repr__(self):
return f"Point({self.x}, {self.y})"
point = Point(3, 4)
print(point)
print(repr(point))
文件基础操作、读写
- 定义:文件操作是对计算机中的文件进行读取、写入、修改等操作。在Python中,使用 open 函数打开文件,通过文件对象的方法进行读写操作。
- 例题:打开一个文本文件,读取内容并打印,然后写入新的内容。
- 代码:
# 读取文件
file = open('example.txt', 'r')
content = file.read()
print(content)
file.close()
# 写入文件
file = open('example.txt', 'w')
file.write("这是新写入的内容")
file.close()
访问模式、文件定位
- 定义:文件访问模式决定了对文件的操作方式,如只读( r )、只写( w )、追加( a )等;文件定位用于在文件中移动读写指针的位置。
- 例题:以不同访问模式打开文件,使用 seek 方法进行文件定位并读取内容。
- 代码:
# 以只读模式打开文件
file = open('example.txt', 'r')
file.seek(5) # 将指针移动到第5个字节位置
content = file.read(10) # 从指针位置读取10个字节
print(content)
file.close()
# 以追加模式打开文件
file = open('example.txt', 'a')
file.write("\n这是追加的内容")
file.close()
with open、编码格式及目录获取
- 定义: with open 语句用于自动管理文件的打开和关闭,确保文件在使用后正确关闭;编码格式指定文件内容的编码方式;获取目录操作可以获取当前工作目录或指定目录下的文件列表等信息。
- 例题:使用 with open 读取和写入文件,指定编码格式,获取当前工作目录。
- 代码:
import os
# 使用with open读取文件
with open('example.txt', 'r', encoding='utf - 8') as file:
content = file.read()
print(content)
# 使用with open写入文件
with open('new_file.txt', 'w', encoding='utf - 8') as file:
file.write("这是新创建文件的内容")
# 获取当前工作目录
current_dir = os.getcwd()
print("当前工作目录:", current_dir)
可迭代对象、迭代器对象
- 定义:可迭代对象是可以一次返回一个元素的对象,如列表、元组、字符串等;迭代器对象是实现了迭代器协议( __iter__ 和 __next__ 方法)的对象,用于遍历可迭代对象。
- 例题:创建一个可迭代对象,将其转换为迭代器对象并进行遍历。
- 代码:
my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)
while True:
try:
element = next(my_iterator)
print(element)
except StopIteration:
break
自定义迭代器类
- 定义:通过定义一个类并实现迭代器协议的方法( __iter__ 和 __next__ ),可以创建自定义的迭代器类,实现特定的迭代逻辑。
- 例题:创建一个自定义迭代器类,用于生成斐波那契数列。
- 代码:
class FibonacciIterator:
def __init__(self, n):
self.n = n
self.a = 0
self.b = 1
self.count = 0
def __iter__(self):
return self
def __next__(self):
if self.count < self.n:
result = self.a
self.a, self.b = self.b, self.a + self.b
self.count += 1
return result
else:
raise StopIteration
fibonacci_iter = FibonacciIterator(10)
for num in fibonacci_iter:
print(num)
生成器及三者关系
- 定义:生成器是一种特殊的迭代器,它使用 yield 语句生成值,而不是一次性返回所有值,从而节省内存;生成器与可迭代对象、迭代器对象密切相关,生成器本质上也是一种迭代器。
- 例题:创建一个生成器函数,生成斐波那契数列,并与自定义迭代器类进行对比。
- 代码:
def fibonacci_generator(n):
a, b = 0, 1
count = 0
while count < n:
yield a
a, b = b, a + b
count += 1
fibonacci_gen = fibonacci_generator(10)
for num in fibonacci_gen:
print(num)
多任务、多线程实现与方法
- 定义:多任务是指在同一时间内执行多个任务,多线程是实现多任务的一种方式,通过在一个进程内创建多个线程来并发执行任务。
- 例题:使用 threading 模块创建多线程,实现多个任务同时执行。
- 代码:
import threading
def task1():
for i in range(5):
print("任务1执行中:", i)
def task2():
for i in range(5):
print("任务2执行中:", i)
thread1 = threading.Thread(target=task1)
thread2 = threading.Thread(target=task2)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
多线程特点、同步与互斥锁
- 定义:多线程的特点包括提高程序的并发性能,但也存在资源竞争等问题;同步是指协调多个线程的执行顺序,避免资源竞争;互斥锁是一种同步机制,用于确保同一时间只有一个线程可以访问共享资源。
- 例题:使用互斥锁解决多线程访问共享资源的冲突问题。
- 代码:
import threading
counter = 0
lock = threading.Lock()
def increment():
global counter
for _ in range(1000):
lock.acquire()
counter += 1
lock.release()
threads = []
for _ in range(5):
thread = threading.Thread(target=increment)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print("最终计数器的值:", counter)
进程介绍与常用属性
- 定义:进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。进程有一些常用属性,如进程ID、进程名称等。
- 例题:使用 multiprocessing 模块创建进程,查看进程的属性。
- 代码:
import multiprocessing
def process_task():
print("当前进程ID:", multiprocessing.current_process().pid)
if __name__ == '__main__':
process = multiprocessing.Process(target=process_task)
process.start()
process.join()
进程方法、变量共享与通信
- 定义:进程有一些方法用于控制进程的执行,如 start 、 join 等;在多进程中,变量共享和通信是需要解决的问题,可通过共享内存、队列等方式实现。
- 例题:使用共享内存和队列实现多进程间的变量共享和通信。
- 代码:
import multiprocessing
def worker1(shared_value, queue):
shared_value.value = 100
queue.put("来自worker1的消息")
def worker2(shared_value, queue):
print("共享变量的值:", shared_value.value)
message = queue.get()
print("接收到的消息:", message)
if __name__ == '__main__':
shared_value = multiprocessing.Value('i', 0)
queue = multiprocessing.Queue()
p1 = multiprocessing.Process(target=worker1, args=(shared_value, queue))
p2 = multiprocessing.Process(target=worker2, args=(shared_value, queue))
p1.start()
p1.join()
p2.start()
p2.join()
协程操作、 greenlet 使用
- 定义:协程是一种轻量级的并发编程方式,在一个线程内实现多个任务的切换执行; greenlet 是一个实现协程的库,通过 greenlet 可以手动切换协程的执行。
- 例题:使用 greenlet 库创建和切换协程。
- 代码:
from greenlet import greenlet
def task1():
print("任务1开始")
gr2.switch()
print("任务1结束")
def task2():
print("任务2开始")
gr1.switch()
print("任务2结束")
gr1 = greenlet(task1)
gr2 = greenlet(task2)
gr1.switch()
gevent 使用、线程进程协程总结
- 定义: gevent 是一个基于 greenlet 的高性能并发库,它自动切换协程,实现异步编程;总结线程、进程、协程的特点、优缺点及适用场景。
- 例题:使用 gevent 实现并发任务,比较线程、进程、协程。
- 代码:
import gevent
def task():
print("任务开始")
gevent.sleep(
网络爬虫
爬虫基础介绍
- 定义:网络爬虫是一种按照一定的规则,自动抓取万维网信息的程序或者脚本。它可以模拟人类浏览器行为,从网页中提取所需数据。
- 例题:分析一个简单网页的结构,思考如何编写爬虫获取其中的文本信息。
- 代码:简单展示使用 requests 库发起HTTP请求获取网页内容的示例代码。
import requests
url = 'http://example.com'
response = requests.get(url)
if response.status_code == 200:
print(response.text)
http协议与请求头
- 定义:HTTP协议是用于从万维网服务器传输超文本到本地浏览器的传送协议。请求头包含了客户端向服务器发送的附加信息,如浏览器类型、接受的数据类型等,用于协助服务器处理请求。
- 例题:通过分析浏览器开发者工具中的网络请求,查看不同请求的请求头信息,理解其作用。
- 代码:在 requests 请求中添加自定义请求头。
import requests
url = 'http://example.com'
headers = {
'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
print(response.text)
requests库介绍
- 定义: requests 库是Python的第三方HTTP库,它简化了HTTP请求的发送和处理过程,支持GET、POST等多种请求方法,能方便地处理响应数据。
- 例题:使用 requests 库发送GET和POST请求,获取不同类型的响应数据(如JSON、HTML)。
- 代码:
# GET请求获取JSON数据
import requests
url = 'https://api.example.com/data'
response = requests.get(url)
if response.status_code == 200:
data = response.json()
print(data)
# POST请求
url = 'https://example.com/login'
data = {
'username': 'testuser',
'password': 'testpass'
}
response = requests.post(url, data=data)
if response.status_code == 200:
print(response.text)
url传参
- 定义:在URL中传递参数,用于向服务器指定查询条件、操作指令等信息。参数通常以键值对的形式附加在URL的末尾,通过 ? 与URL主体分隔,多个参数之间用 & 连接。
- 例题:编写一个爬虫,通过URL参数获取不同页面的商品信息。
- 代码:
import requests
base_url = 'https://example.com/products'
params = {
'page': 2,
'category': 'electronics'
}
response = requests.get(base_url, params=params)
if response.status_code == 200:
print(response.text)
网易云案例
- 定义:以网易云音乐为例,运用爬虫技术获取音乐列表、歌曲详情、用户评论等信息,深入理解爬虫在实际网站中的应用。
- 例题:爬取网易云音乐某歌手的热门歌曲列表。
- 代码:
import requests
import json
url = 'https://music.163.com/weapi/v3/artist/top/song'
headers = {
'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Content - Type': 'application/x-www-form-urlencoded'
}
data = {
'id': 12345, # 歌手ID
'limit': 10,
'offset': 0
}
response = requests.post(url, headers=headers, data=data)
if response.status_code == 200:
result = json.loads(response.text)
for song in result['songs']:
print(song['name'])
post请求与模拟登录
- 定义:POST请求用于向服务器提交数据,模拟登录是通过发送包含用户名和密码等登录信息的POST请求,获取登录后的用户权限,从而访问需要登录才能查看的页面数据。
- 例题:模拟登录某网站,获取登录后的用户个人信息。
- 代码:以某简单网站为例,实际代码需根据目标网站登录逻辑调整。
import requests
url = 'https://example.com/login'
data = {
'username': 'your_username',
'password': 'your_password'
}
session = requests.Session()
response = session.post(url, data=data)
if response.status_code == 200:
user_info_url = 'https://example.com/userinfo'
user_response = session.get(user_info_url)
if user_response.status_code == 200:
print(user_response.text)
代理ip
- 定义:代理IP是一种网络服务器,它作为客户端和目标服务器之间的中介,客户端通过代理IP发送请求,目标服务器看到的是代理IP的地址而非客户端真实IP,可用于突破IP访问限制、隐藏真实IP等。
- 例题:使用代理IP访问被限制的网站。
- 代码:
import requests
url = 'https://example.com'
proxies = {
'http': 'http://your_proxy_ip:port',
'https': 'https://your_proxy_ip:port'
}
response = requests.get(url, proxies=proxies)
if response.status_code == 200:
print(response.text)
数据类型介绍
- 定义:在爬虫中,常见的数据类型有文本(HTML、XML、纯文本等)、JSON、二进制数据(图片、音频、视频等)。不同的数据类型需要不同的处理方式。
- 例题:识别不同网页响应数据的类型,并针对不同类型进行初步处理。
- 代码:判断响应数据类型为JSON时的处理。
import requests
url = 'https://example.com/api/data'
response = requests.get(url)
if response.status_code == 200:
try:
data = response.json()
print(data)
except ValueError:
print('响应数据不是JSON格式')
json与jsonpath
- 定义:JSON是一种轻量级的数据交换格式,易于阅读和编写,也易于机器解析和生成;JSONPath是一种用于在JSON数据中查找和提取数据的表达式语言,类似于XPath用于XML。
- 例题:使用JSONPath从复杂的JSON数据中提取特定信息。
- 代码:
import json
import jsonpath
json_data = {
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
]
}
}
titles = jsonpath.jsonpath(json_data, '$.store.book[*].title')
print(titles)
xpath使用
- 定义:XPath是一门在XML文档中查找信息的语言,也可用于在HTML文档中定位元素。它通过路径表达式来选取XML文档中的节点或者节点集。
- 例题:使用XPath从HTML页面中提取所有链接。
- 代码:
from lxml import etree
html = """
<html>
<body>
<a href="https://example1.com">链接1</a>
<a href="https://example2.com">链接2</a>
</body>
</html>
"""
tree = etree.HTML(html)
links = tree.xpath('//a/@href')
for link in links:
print(link)
腾讯课堂评论数据获取
- 定义:运用爬虫技术获取腾讯课堂课程的用户评论数据,分析用户对课程的评价和反馈。
- 例题:爬取某腾讯课堂课程的前100条评论。
- 代码:需根据腾讯课堂的实际接口和反爬机制调整,这里仅为示例框架。
import requests
import json
url = 'https://ke.qq.com/course/comment'
headers = {
'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
params = {
'course_id': 12345, # 课程ID
'page': 1,
'page_size': 10
}
comments = []
for i in range(10):
params['page'] = i + 1
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
result = json.loads(response.text)
comments.extend(result['data']['comments'])
for comment in comments:
print(comment['content'])
数据入库
- 定义:将爬取到的数据存储到数据库中,方便后续的查询、分析和管理。常见的数据库有MySQL、MongoDB等,不同数据库适用于不同类型的数据存储需求。
- 例题:将爬取的腾讯课堂评论数据存储到MySQL数据库中。
- 代码:
import mysql.connector
import requests
import json
# 连接MySQL数据库
mydb = mysql.connector.connect(
host="localhost",
user="your_user",
password="your_password",
database="your_database"
)
mycursor = mydb.cursor()
url = 'https://ke.qq.com/course/comment'
headers = {
'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
params = {
'course_id': 12345,
'page': 1,
'page_size': 10
}
for i in range(10):
params['page'] = i + 1
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
result = json.loads(response.text)
for comment in result['data']['comments']:
sql = "INSERT INTO comments (content, user_id, create_time) VALUES (%s, %s, %s)"
val = (comment['content'], comment['user_id'], comment['create_time'])
mycursor.execute(sql, val)
mydb.commit()
mydb.close()
b站视频数据处理
- 定义:对B站视频相关数据进行爬取和处理,如视频标题、播放量、弹幕等,分析视频的热度和用户反馈。
- 例题:爬取B站某视频的弹幕数据并进行词频分析。
- 代码:
import requests
import xml.etree.ElementTree as ET
from collections import Counter
video_id = 'BV123456789'
url = f'https://comment.bilibili.com/{video_id}.xml'
response = requests.get(url)
if response.status_code == 200:
root = ET.fromstring(response.content)
danmaku_texts = [d.text for d in root.findall('d')]
word_counter = Counter()
for text in danmaku_texts:
words = text.split()
word_counter.update(words)
top_words = word_counter.most_common(10)
for word, count in top_words:
print(f'{word}: {count}')
selenium测试工具及使用
- 定义:Selenium是一个用于Web应用程序测试的工具,也可用于爬虫。它可以驱动浏览器进行自动化操作,如点击按钮、填写表单、滚动页面等,适用于处理动态网页。
- 例题:使用Selenium模拟登录B站并获取用户关注列表。
- 代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome()
driver.get('https://www.bilibili.com/login')
# 填写用户名和密码
driver.find_element(By.ID, 'login-username').send_keys('your_username')
driver.find_element(By.ID, 'login-passwd').send_keys('your_password')
# 点击登录按钮
driver.find_element(By.CLASS_NAME, 'btn - btn').click()
time.sleep(3)
# 获取关注列表
driver.get('https://space.bilibili.com/your_user_id/fans/follow')
follow_list = driver.find_elements(By.CSS_SELECTOR, '.user - info__name')
for follow in follow_list:
print(follow.text)
driver.quit()
js加密、逆向解析案例
- 定义:一些网站为了防止数据被轻易爬取,会对关键数据进行JavaScript加密。逆向解析就是通过分析网站的JavaScript代码,找出加密算法,并还原数据的过程。
- 例题:分析某网站登录密码的加密算法,实现密码加密和登录请求。
- 代码:以某简单加密算法为例,实际需根据具体网站代码分析。
import execjs
import requests
# 假设网站使用的简单加密算法在encrypt.js文件中
with open('encrypt.js', 'r', encoding='utf - 8') as f:
js_code = f.read()
ctx = execjs.compile(js_code)
password = 'your_password'
encrypted_password = ctx.call('encrypt', password)
url = 'https://example.com/login'
data = {
'username': 'your_username',
'password': encrypted_password
}
response = requests.post(url, data=data)
if response.status_code == 200:
print(response.text)
起点月票榜数据分析相关案例
- 定义:爬取起点中文网月票榜数据,对小说的排名、票数、作者等信息进行分析,了解网络文学市场的热度和趋势。
- 例题:爬取起点月票榜前50名小说信息并分析月票分布。
- 代码:
import requests
from lxml import etree
import matplotlib.pyplot as plt
url = 'https://www.qidian.com/rank/yuepiao'
response = requests.get(url)
if response.status_code == 200:
tree = etree.HTML(response.text)
novels = []
for item in tree.xpath('//div[@class="rank - item"]'):
novel = {
'rank': item.xpath('.//span[@class="rank - order"]/text()')[0],
'title': item.xpath('.//h2/a/text()')[0],
'votes': int(item.xpath('.//div[@class="book - votes"]/span/text()')[0])
}
novels.append(novel)
ranks = [int(novel['rank']) for novel in novels]
votes = [novel['votes'] for novel in novels]
plt.bar(ranks, votes)
plt.xlabel('排名')
plt.ylabel('月票数')
plt.title('起点月票榜月票分布')
plt.show()
字体加密文件、关系分析
- 定义:字体加密是一种反爬虫手段,网站通过将特殊字符映射到自定义字体文件中,使爬虫难以直接获取真实文本。关系分析则是研究字体文件中字符映射关系以及与网页文本的对应关系,从而破解加密。
- 例题:分析某网站字体加密文件,还原网页中的真实文本。
- 代码:需使用专业字体分析库,如 fonttools ,这里仅为示例框架。
from fonttools.ttLib import TTFont
# 下载字体文件
url = 'https://example.com/font.woff'
response = requests.get(url)
with open('font.woff', 'wb') as f:
f.write(response.content)
font = TTFont('font.woff')
# 分析字体文件中的字符映射关系
# 这里省略复杂的分析过程,实际需根据字体文件结构解析
# 假设解析出映射字典mapping
mapping = {'uni1234': '你', 'uni5678': '好'}
# 假设网页文本中
验证码、打码平台介绍与使用
- 定义:验证码是一种区分用户是计算机还是人的公共全自动程序,常见的有图形验证码、短信验证码、语音验证码等。打码平台是将验证码识别工作众包给人工或利用OCR等技术结合人工辅助来识别验证码的服务平台,爬虫可以借助打码平台获取验证码的识别结果以突破验证码限制。
- 例题:在模拟登录某网站时,使用打码平台识别图形验证码并完成登录。
- 代码:以某打码平台为例,假设该平台提供API接口
import requests
from PIL import Image
import base64
# 发起登录请求,获取验证码图片
login_url = 'https://example.com/login'
response = requests.get(login_url)
captcha_url = 'https://example.com/captcha.jpg'
captcha_response = requests.get(captcha_url)
with open('captcha.jpg', 'wb') as f:
f.write(captcha_response.content)
# 将验证码图片转换为base64编码,以便传给打码平台
with open('captcha.jpg', 'rb') as f:
image_data = f.read()
base64_image = base64.b64encode(image_data).decode('utf - 8')
# 向打码平台发送请求,获取识别结果
platform_url = 'https://your_captcha_platform.com/api/recognize'
data = {
'image': base64_image,
'type': 'image' # 表明是图形验证码
}
platform_response = requests.post(platform_url, json=data)
if platform_response.status_code == 200:
captcha_text = platform_response.json()['result']
# 使用识别结果进行登录
login_data = {
'username': 'your_username',
'password': 'your_password',
'captcha': captcha_text
}
login_result = requests.post(login_url, data=login_data)
if login_result.status_code == 200:
print('登录成功')
else:
print('登录失败')
else:
print('验证码识别失败')
移动端数据获取
- 定义:获取移动应用中的数据,与网页爬虫不同,移动端数据获取需要考虑移动应用的架构、通信协议等因素。可以通过抓包工具获取移动应用与服务器之间的通信数据,也可以利用一些针对移动端的自动化测试工具模拟用户操作获取数据。
- 例题:使用抓包工具获取某移动电商应用的商品列表数据。
- 代码:使用 mitmproxy 进行抓包示例(Python中可结合 mitmproxy 的API进行数据处理)
# 假设已经安装并配置好mitmproxy,这里展示如何在Python中使用其API处理抓包数据
from mitmproxy import http
def response(flow: http.HTTPFlow):
if 'https://your_mobile_app_api.com/products' in flow.request.url:
data = flow.response.json()
for product in data['products']:
print(product['name'], product['price'])
抓包工具设置与介绍
- 定义:抓包工具用于捕获网络数据包,分析网络通信的内容、协议、请求和响应等信息。常见的抓包工具有Wireshark、Fiddler、Charles等,在爬虫中主要用于分析目标网站或应用的通信规律,获取请求参数、响应数据等。
- 例题:使用Charles设置代理,抓取手机端应用的网络请求,并分析请求头和响应数据。
- 代码:无直接代码,主要是操作步骤:
- 打开Charles,设置代理端口(如8888)。
- 在手机端设置代理,将代理服务器设置为电脑IP,端口为Charles设置的端口。
- 打开手机应用,在Charles中查看捕获的请求,分析请求头(如 User - Agent 、 Cookie 等)和响应数据(如JSON、HTML等)。
移动设备、安卓模拟器设置及关系
- 定义:移动设备是运行移动应用的终端,安卓模拟器是在计算机上模拟安卓系统环境的软件,可用于运行安卓应用。在爬虫中,使用安卓模拟器可以方便地在电脑上进行移动端数据获取的测试和开发,其设置包括安装模拟器、配置网络、安装应用等步骤,与真实移动设备在数据获取原理上相似,但在操作便利性和性能上有所不同。
- 例题:在电脑上安装夜神模拟器,在模拟器中安装某移动应用,并使用爬虫技术获取应用内数据。
- 代码:结合 uiautomator2 库(用于安卓自动化测试和数据获取)
import uiautomator2 as u2
# 连接模拟器,假设模拟器默认端口7912
d = u2.connect('127.0.0.1:7912')
# 启动应用,假设应用包名为com.example.app
d.app_start('com.example.app')
# 模拟点击操作,获取数据(这里假设点击某个按钮后会加载数据)
d(resourceId="com.example.app:id/button_id").click()
# 获取页面文本数据
text = d(text="相关数据所在文本区域的特征").get_text()
print(text)
微博热搜榜分析与获取
- 定义:微博热搜榜是反映当前热门话题和事件的榜单,通过爬虫获取热搜榜数据,并进行分析,如统计话题热度趋势、话题分类等,有助于了解社会热点和舆情。
- 例题:爬取微博实时热搜榜前50个话题及其热度,并绘制热度排名图表。
- 代码:
import requests
import json
import matplotlib.pyplot as plt
url = 'https://weibo.com/ajax/statuses/hot_band'
headers = {
'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = json.loads(response.text)
hot_topics = []
for item in data['data']['band_list']:
topic = {
'rank': item['rank'],
'title': item['note'],
'heat': item['heat']
}
hot_topics.append(topic)
ranks = [topic['rank'] for topic in hot_topics]
heats = [topic['heat'] for topic in hot_topics]
plt.bar(ranks, heats)
plt.xlabel('排名')
plt.ylabel('热度')
plt.title('微博热搜榜热度分布')
plt.show()
爬虫框架介绍、工作流程及组件
- 定义:爬虫框架是一个为了减少爬虫开发的工作量,提高开发效率而设计的软件架构,常见的爬虫框架有Scrapy、Beautiful Soup等。以Scrapy为例,它的工作流程包括从初始URL开始发送请求,下载器下载页面,解析器解析页面提取数据或新的URL,然后将数据存储或进一步处理,其组件包括引擎(Engine)、调度器(Scheduler)、下载器(Downloader)、蜘蛛(Spider)、项目管道(Item Pipeline)等。
- 例题:分析Scrapy框架的工作流程,绘制流程图并解释各组件的作用。
- 代码:无直接代码,主要是理论分析和流程图绘制。在Scrapy中,引擎负责控制整个流程的运行,调度器管理待爬取的URL队列,下载器负责下载网页,蜘蛛负责解析网页和提取数据,项目管道负责处理和存储提取到的数据。
项目创建、爬虫文件设置
- 定义:在使用爬虫框架时,首先需要创建一个项目,然后在项目中设置爬虫文件。以Scrapy为例,使用 scrapy startproject 命令创建项目,在项目中创建蜘蛛文件( .py 文件),在蜘蛛文件中定义爬虫的逻辑,包括起始URL、解析规则等。
- 例题:使用Scrapy创建一个爬取某新闻网站文章的项目,并设置爬虫文件。
- 代码:
bash
# 创建Scrapy项目
scrapy startproject news_crawler
cd news_crawler
在 news_crawler/spiders 目录下创建 news_spider.py 文件:
import scrapy
class NewsSpider(scrapy.Spider):
name = 'news'
start_urls = [
'https://example.com/news'
]
def parse(self, response):
for article in response.css('div.article'):
yield {
'title': article.css('h2.title::text').get(),
'content': article.css('div.content::text').get()
}
项目与任务组成、基本使用总结
- 定义:一个爬虫项目通常由多个任务组成,如数据抓取、数据清洗、数据分析、数据存储等。在使用爬虫框架时,需要了解项目的整体结构和各个任务的实现方式,以及如何配置和运行项目。
- 例题:总结爬取某电商网站商品信息项目的任务组成和实现步骤,包括创建项目、设置爬虫、处理数据、存储数据等。
- 代码:以Scrapy为例,整体项目代码结构包括项目配置文件( settings.py )、爬虫文件( .py )、数据处理管道文件( pipelines.py )等。在 settings.py 中配置数据库连接、设置请求头、开启数据处理管道等;在爬虫文件中定义爬取逻辑;在 pipelines.py 中实现数据存储逻辑,如将数据存储到MySQL数据库:
# pipelines.py
import mysql.connector
class MySQLPipeline:
def __init__(self, host, user, password, database):
self.host = host
self.user = user
self.password = password
self.database = database
@classmethod
def from_crawler(cls, crawler):
return cls(
host=crawler.settings.get('MYSQL_HOST'),
user=crawler.settings.get('MYSQL_USER'),
password=crawler.settings.get('MYSQL_PASSWORD'),
database=crawler.settings.get('MYSQL_DATABASE')
)
def open_spider(self, spider):
self.connection = mysql.connector.connect(
host=self.host,
user=self.user,
password=self.password,
database=self.database
)
self.cursor = self.connection.cursor()
def close_spider(self, spider):
self.cursor.close()
self.connection.close()
def process_item(self, item, spider):
sql = "INSERT INTO products (title, price) VALUES (%s, %s)"
val = (item['title'], item['price'])
self.cursor.execute(sql, val)
self.connection.commit()
return item
数据提取、保存、翻页操作
- 定义:数据提取是从网页或其他数据源中获取所需数