python_网站调用24小时内容怎么设置-程序员宅基地

技术标签: 爬虫  python  服务器  数据库  

python 第一天

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

python源

1.临时修改

C:\Users\huya>pip install requests -i http://pypi.douban.com/simple/
Looking in indexes: http://pypi.douban.com/simple/
Requirement already satisfied: requests in d:\program files\python39\lib\site-packages (2.31.0)
Requirement already satisfied: certifi>=2017.4.17 in d:\program files\python39\lib\site-packages (from requests) (2023.11.17)
Requirement already satisfied: charset-normalizer<4,>=2 in d:\program files\python39\lib\site-packages (from requests) (3.3.2)
Requirement already satisfied: urllib3<3,>=1.21.1 in d:\program files\python39\lib\site-packages (from requests) (2.1.0)
Requirement already satisfied: idna<4,>=2.5 in d:\program files\python39\lib\site-packages (from requests) (3.6)
WARNING: You are using pip version 20.2.3; however, version 23.3.2 is available.
You should consider upgrading via the ‘d:\program files\python39\python.exe -m pip install --upgrade pip’ command.

C:\Users\huya>

2.永久修改

pip config set global.index-url http://pypi.douban.com/simple/

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

换回默认源

pip config unset global.index-url

C:\Users\huya>pip config set global.index-url http://pypi.douban.com/simple/

Writing to C:\Users\huya\AppData\Roaming\pip\pip.ini

C:\Users\huya>

升级pip

​ python -m pip install --upgrade pip

C:\Users\huya>python -m pip install --upgrade pip

Looking in indexes: http://pypi.douban.com/simple/
WARNING: The repository located at pypi.douban.com is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow it anyway with '--trusted-host pypi.douban.com'.
Requirement already up-to-date: pip in d:\program files\python39\lib\site-packages (20.2.3)
WARNING: The repository located at pypi.douban.com is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow it anyway with '--trusted-host pypi.douban.com'.

C:\Users\huya>
C:\Users\huya>python -m pip install --upgrade pip --trusted-host pypi.douban.com
Looking in indexes: http://pypi.douban.com/simple/
Collecting pip
  Downloading https://mirrors.cloud.tencent.com/pypi/packages/15/aa/3f4c7bcee2057a76562a5b33ecbd199be08cdb4443a02e26bd2c3cf6fc39/pip-23.3.2-py3-none-any.whl (2.1 MB)
     |████████████████████████████████| 2.1 MB 1.7 MB/s
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 20.2.3
    Uninstalling pip-20.2.3:
      Successfully uninstalled pip-20.2.3
Successfully installed pip-23.3.2

C:\Users\huya>

安装request 报错

pip install requests 报错 要添加信任

解决方法: pip install requests --trusted-host pypi.douban.com

虚拟环境

pip虚拟环境 --分离分割开发项目,保持项目环境纯净,互补影响

基本输入输出

#input print 内建函数  --自带的
# print("hello")
#
# str = input("请输入一串字符串:\n")
# print("接收到的字符串:",str)

#input 从键盘接收到的都是字符串类型
# num1 = input("请输入一个整数:")
# print(type(num1)) #type 查看数据类型
#
# #num2 = num1+100
# num3 =int(num1)+200
# print(type(num1),num3)

# #输出-- print  自动添加换行和空格
# #sep 指定分隔符  默认是空格
# #end 指定结尾字符  默认是换行符
# print("abc",end="%%%")
# print("abc","xyz",sep="#*#")

#同一行中有多个语句 使用分号隔开
print("xixixi");print("hahah")
#一行语句没有结束,可以使用续航符
print("hello \
       world")

# 练习  模拟用户登录 从键盘防护乳和密码判断是否为123456
print("请输入用户名:")
name=input()
if name=="root":
    print("请输入密码")
    passwd = input()
    if(passwd=="123456"):
        print("登录成功")
    else:
        print("密码错误,请重新输入")
else:
    print("用户名错误")

安装python3 软件

yum install python3 -y

使用python3

[root@localhost ~]# python3
Python 3.6.8 (default, Nov 14 2023, 16:29:52)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type “help”, “copyright”, “credits” or “license” for more information.

python3 e3.py //使用python3 运行文件e3.py

w3cschool

在函数内部更改全局变量

python

python基本语法和基本输入输出:

#单行注释 使用#
"""
多行注释使用三引号
12345
python 动态类型语言
"""
a=100
a,b=100,200 #python 赋值 不需要声明直接赋值
a,b = b,a# 交换赋值
#变量名的命名规则和go语言一样 
#可以使用中文作为变量名 可以但没必要
#以缩进来区分代码块 必须要处理好缩进 以代码来分级 同一个语句块保持同级
#最好使用四个空格缩进
a = 100
if a>100 : #注意冒号
    print("a大于100")
else:      #注意冒号
    print("a小于100")

同一行中有多个语句用分号隔开

print("xixi");print("haha")

一行语句没有结束,可以使用续行符 \ 接第二行语句

print("hello \
      world")
# str = input("请输入一串字符串")
# print("接收到的字符串:",str)
num1 = input("请输出一个整数:")
num2 = num1+"100"
num3 = int(num1) + 200
print( type(num1), num2, num3)  #type查看数据类型
#输出-- print 自动添加换行符和空格分隔符
#sep 指定分隔符  默认是空格
#end 指定结尾字符  默认是换行符
print("abc",end="%%%")
print("abc","xyz",sep="#*#")

python3

yum install python3 -y

Python 3.6.8 (default, Nov 14 2023, 16:29:52)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type “help”, “copyright”, “credits” or “license” for more information.

在linux上完成python的简易代码:

#!/usr/bin/python3 //默认使用python3解释器

num1 = int(input(“请输入number1:”))
*num2 = int(input(“请输入number2:”))
sum_result = num1 + num2
print(f"result={sum_result}")

python2不支持中文的字符集

python3可以支持中文的字符集

流程控制 control flow --》流控

if条件判断 循环语句: loop statement

for while

跳出循环: break continue

关键字–key word :python内部内置的一些名词(变量名),不允许我们自定义变量的时候使用

isdigit()是一个方法,理解为python里自带的 python编程里一切皆对象 num是对象

isalpha 判断是否是字母 isalnum 判断是否是字母和数字 isdigit 判断是否是数字 num.isnumeric 判断是否是数字 isupper 判断是否是大写字母 islower 判断是否是小写字母 isidentifier 判断字符串是否可以做变量名
isspace 判断是否是空格
isdecimal 是否是浮点数

[root@localhost python]# cat e2.py
num = input(“please input number:”)
if num.isdigit():
num = int(num)
if num == 80:
print(“good”)
elif num > 80:
print(“greater than 80”)
elif num > 70:
print(“greater than 70”)
else:
print(“less than 70”)
else:
print(“请输入数字”)
[root@localhost python]

容器类型: container 理解为装数据的地方 列表 list —》 C语言数组 元素之间用逗号隔开


for 循环控制次数

while控制循环次数 死循环:

i = 1
while True:
print(f"sanchuang{i}")
i += 1


变量的个数 1 值在变化 --》执行加法运算》cpu

模块 :本质就是.py文件,理解为别人造好的轮子,直接使用 import 进口 导入 export 出口

import time time.sleep(1) -->sleep 属于time python 文件里的一个函数 (方法) 一个函数实现一个功能 function

i = 1
while True:
print(f"sanchuang{i}")
i += 1
time.sleep(1)


python里的一些模块:requests 、 random 、time

i = 1
while True:
print(f"sanchuang{i}")
i += 1
time.sleep(1)
if i == 5:
break
print(“class over”)

[root@localhost python]#

break 跳出循环,不再执行循环后面的语句
continue 跳出本次循环,接着执行下一个循环

扩展:
导入模块 import
random
time
os

	if
	for
	while
	break
	continue
	运算符  + - * / %  **  //
	     > == != <  >= <=
	关键字
	成员关系判断
		in
		not in
		列表 字典 元组
		字符串自带的方法
		isupper()
	计数功能               

数据类型

#!/usr/bin/env python
# @FileName :shuzhileixing.py
# @Time :2024/1/18 10:23
# @Author :mingshui
#整数类型 -- int
#浮点型 -- float 不精确
# decimal  --精确
#复数 -- complex

#字符串类型
#定义 -- 单引号、双引号、三引号
str1 ='abc'
str2 = "abc"
str3 = '''
abc
123
'''
str4 ="ab'c"
str5 = 'ab"c'
print( type(str1) )
print (str4,str5) #不要使用str作为变量名
#>>> str(a) 类型转换函数
#>>> str='abc'   不要使用内建函数的名字作为变量名

#转义字符
print("a\tb")
print("a\nb")
print("a\\tb")
print("\"")
print(r"a\tb")  #原始标记位,不转义,原样输出
## 字符串截取处理
#str[start:end:step]
#确定step是正还是负
#  为正  从前往后截取
#   为负 从后往前截取
#确定start和end的位置,start在截取方向上要在end的前面
# 确定步长

str1 = "abcdefjhi"
print(str1[5],str1[-2])
print(str1[2:6])
print(str1[:5],str1[2:])
print(str1[6::-1])
print(str1[2:8:2])
print(str1[-2:2:-1])
print(str1[2:-2:-1])
print(str1[-1::-1])
#字符串的拼接和级连
str1 ="xyz" "abc"
print(str1)
str2 = "xyz"+"abc"
print(str2)
str3 = "abc"*3
print(str3)
#控制格式输出
print("{0:x}".format(30))
#python3 -- 标志位格式化(f)
name = "sctl"
age = 18
print(f"my name is {
      name},my age is {
      age+1}")
#字符串的遍历
for i in  "abcxyz中文":
    print("获取到的i为:",i)
for k,v in  enumerate("abcxyz"):
    print(f"{
      k} --> {
      v}")
#python字符串的常用属性 -- 类似go语言的strings包
#属性 -- 对象的方法
#属性方法   对象名.属性名   对象名.方法名()
print( dir("abc"))
print("xyzABC".upper())
#判断系列
print(f"判断是不是全为数字:{
      '123456'.isdigit()}")
print(f"判断是不是标题字符:{
      'A Beautiful girl'.isdigit()}")
print(f"判断开头:{"qwerxyz".startswith('qw')}")  # 判断字符串是不是以qw开头
print(f"判断结尾:{"qwerxyz".endswith('qw')}")  # 判断字符串是不是以qw结尾
print(f"判断合法标识符".isidentifier())
print(f"判断可打印符".isprintable())
print(f"判断是否全为小写".islower())
print(f"判断是否只包含空格".isspace())
#查找统计
print(f"长度统计:{
       len('abc中文')}")
print(f"查看第一次出现的下标位置,没有就抛出异常:{
      'abccc'.index('c') }")
print(f"查看第一次出现的下标位置,没有就返回-1:{
      'abccc'.find('x') }")

#字符串转换类
print(f"转换为大写:{
      'abc'.upper()}")
print(f"转换为小写:{
      'abc'.lower()}")
print(f"字符串切割:{
      'a:bc:de'.split(':')}")
lst = ['a','bbbb','c']
result = "*".join(lst)
print(result)
#去除收尾空白字符--strip
print(f"  ab  c  ".strip())
print(f"#ab#c#".strip('#'))
#替换 --- replace
str1 = "xxxxyyyy".replace("x","%",1)
print(str1)


#填充
print("欢迎进入三创系统".center(50,"*"))
print("1,登录".ljust(10,"*"))
print("2,注册".ljust(10,"*"))
#布尔类型 -- 判断
#true --1
#False --0
#可直接参与计算
# >>>"abc".islower() + "XYZ".isupper()
#2

#有一些数值可以直接就表示真假
#为假
# ""、0、0.0、[]、()、{}、None  这些都表示假
#None --nil  表示什么都没有 -- NoneType

str1 = input("请输入一个字符串:")
if str1:
    print(str1)
else:
    print("str1为空")
--------------------------------------------------
    num1 = int(input("请输入一个字符串:"))
if num1%2 == 1:
    print("num1 是奇数")
else:
    print("num1是偶数")

python运算符

幂数运算符 + - * / % ** // #**幂运算 #// 地板除 向下取最接近除数的整数

print(2 ** 3)
print(5 // 2)
print(-5 // 2)
print( 5/2 )
#赋值运算符 += -= *= /= %=
#  a +=  1   --> a=a+1

#比较运算符  ==  !=  <=  >=  >  <
#返回bool类型   运算可以连用
# 5<a<15

#逻辑运算符  not  and  or
#exp1  and exp2  -->  5<a<15  --> 5<a  and  a<15
#exp1 or exp2    --> a<5 or a>15
#not exp1  取反

#短路运算
print(3 and 4)
print(0 and 4)
print(3 or 4)
#a、b是两个非零的整数,取a、b中的最大值,使用逻辑运算符实现
a=10
b=20
max=a>b and a or b #看前面是否为真在判断后面用哪侧
print(max)
#整个表达式 从左至右运算
#若or的左侧为真,则整个表达式的结果为真,短路后面所有表达式
#若and的左侧为假,则短路后面所有相连的and表达式
result = print("hello")
print(result)
result = 3 and print("test1") or 5 and print("test2")
print(f"result is {
      result}")
result = 3 or print("4") and print("5") or 6 or 7
print(f"result is {
      result}")
result = print("test1") and print("test2") and print("test3") or 4 and print("test4")
print(f"result is {
      result}")
#建议:如果连接的逻辑运算表达式非常多,先做结合再计算

#成员关系运算符
#in 、 not in
print("a"in "abc")

#对象实力测试运算符
# is、 is not  用来判断在内存中,是不是同一个内存对象
a = 500
b = 500
print(a is b)

x = y = 500
print()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#顺序结构 -- 基石
#循环结构  --  for、 while
#分支结构 -- if 、 switch、case(新版本支持

#if 条件:
#  执行语句
#else:
#  执行语句

#if 条件1:
#  执行语句
#elif  条件1:
#  执行语句
#else:
#  执行语句
#支持嵌套

#if的三元运算 --if的一个简写
a,b = 10, 20
max = a if a>b else b
#从键盘接收一个数,如果是输入的是偶数,求取平方值。如果输入是奇数,求取这个数本身
num = int(input("请输入一个数值:"))
result = num ** 2 if num % 2 == 0 else num**2
print( result)
#循环结构
for i in range(10):
    if i == 2:
        continue  #跳出本次循环,开启下一次循环
        print("*"*1)
        print(i)
        if i == 5:
            break #终止循环
else:   #循环体正常退出,执行else里的内容
        print("end....")    
#接收一个字符串,将字符串去重处理
str1 = input("请输入字符串")
str2 = ""
for i in str1:
    flag = 0
    for j in str2:
        if i == j:
            flag = 1
            break
        if flag == 0:
           str2+= i  
     print(str2)
        
###---------------------------------------------------
#接收一个字符串,将字符串去重处理
str1 = input("请输入字符串")
str2 = ""
for i in str1:
    # flag = 0
    for j in str2:
        if i == j:
            # flag = 1
            break
        else:
            str2 += i
        # if flag == 0:
        #    str2+= i
    print(str2)
#while 循环
#while  条件为真:
#''   循环体语句
#else:
#  循环正常退出执行
count = 0
while count <5:
    print(f"count is {
      count}")
    count += 1
else:
    print("end......")

###练习:输入任意两个三位整数,相加之后,分别求取它的个位数、十位数、百位数、千位数。无限次数输入,按q退出
while True:
    num1 = input("请输入第一个数值(输入 q 退出):")
    if num1 == "q": #按q退出
        break
    num1 = int(num1)

    num2 = input("请输入第二个数值(输入 q 退出):")
    if num2 == "q": #按q退出
        break
    num2 = int(num2)

    num3 = num1 + num2 #完成相加
    o_num = num3 % 10  # 求取个位数
    e_num = (num3 // 10) % 10  # 求取十位数
    h_num = (num3 // 100) % 10  # 求取百位数
    t_num = (num3 // 1000) % 10  # 求取千位数

    print("个位数:", o_num)
    print("十位数:", e_num)
    print("百位数:", h_num)
    print("千位数:", t_num)
#Python中内置数据结构  属于基本数据类型
#列表、元组、字典、集合、字符串、浮点型、整型、复数、布尔
#容器类型:字符串、列表、元组、字典、集合

#list -- 类似go slice
#1、有序项目集合
#2、可变数据类型
#3、存放任何数据类型

#定义列表 -- list    内建函数 --- python内置
lst = []
lst2 = list()
lst3 = list("abc") #工厂函数。他可以把其他数据类型转化成list,传递可迭代对象(能被for循环遍历的)
print(type(lst),type(lst2),type(lst3))
print(lst3)
# list = ["a","b","c"]#不要用内建函数名字作为变量
 #有序项目集合  --跟字符串类似
lst = ["abb","bx","c","d","e","f"]
print(lst[4],lst[-2])
print(lst[-1:1:-2])

 #可以存放任何数据类型
lst2 = [1,"abc",2.3,None,print()]
print(lst2)

 #可变数据类型对象
 #在原内存地址空间上,可以修改的,就是可变数据类型
lst = list (range(10))
print(lst,id(lst))
lst[0] = 1000
print(lst,id(lst))
str1 = "abcdefg"
print(str1[0])
str1[0] = "x" #不可变数据类型,无法在原地址空间上修改
str1 = "xdcdef" #不可变数据类型修改,只能重新赋值新对象


############
lst = ["a","b","c","d"]
# print( dir(lst) )
# print( help(lst.insert()))

#添加相关属性
#append -- 末尾追加一个元素
lst.append("xyz")
print(lst)
#insert   指定位置去添加元素
lst.insert(2,"*********")
print(lst)
#extend   将其他可迭代对象中的元素,追加到当前列表中来 --  接收可迭代对象的传入
lst.extend(["syz","qwer"])
print(lst)

#列表的删除
#pop ---  可以指定下标删除,默认删除最后一个
result = lst.pop()
print(f"lst is {
      lst},remove element is {
      result}")
result2 = lst.pop(2)
print(f"lst is {
      lst}")


#remove -- 指定元素去删除, 删除指定的第一个元素  列表中没有当前元素,删除会报错
lst.remove("a")
print(lst)

#清空 --- clear
lst.clear()
print(lst)

#列表的修改
lst = ["a","bb","ccc","dddd"]
lst[0] = "aaaaa"
print(lst)
###列表统计
lst = ["a","a","ab","b","xyz"]
print( len(lst) )
print(lst.count("a")) # 统计元素出现的次数
print( lst.index('a')) #统计元素第一次出现的下标位置

#copy属性
lst = ["a","a","ab","b","xyz"]
lst2 = lst
print(id(lst),id(lst2))
lst2[0] = "mm"
print(lst)
lst3 = lst.copy()
print(id(lst3),id(lst))
lst3[0] = "qq"
print(lst)

lst4 = lst[:] #生成新的lst4

#反转和排序
lst = ["x","y","a","b"]
lst.reverse()
print(lst)
lst.sort(reverse=True) #排序
print(lst)
#列表的运算  支持加法和乘法
lst = ["a","b"]
lst2 = ["x","y"]
lst3 = lst + lst2
print(lst3)
print(lst3 * 3)

#列表成员关系判断
print("ab" in ["ab","xyz"])

#列表遍历
for i in ["abc", "xx", "yy"]:
    print(i)
    
for k,v in enumerate(["xx", "yy","zz"]):
    print(f"{
      k} --> {
      v}")  
#30个人,船超载,只能载20个人
#数到第8个人就下船,最后输出哪些人下船了

lst1 = ["person" + str(i) for i in range(1, 31)]
print("船上人员为",lst1)
num = 20# 船只容量
lst2 = [] # 下船的人员列表
index = 19 # 开始遍历人员列表
count = 0
while len(lst1) > num:
    count += 1
    if count == 8:# 数到第八个人
        lst3 = lst1.pop(index)
        lst2.append(lst3)
        count = 0 # 下船
    else:
        index += 1
        if index >= len(lst1):
            index = 0   # 不下船,继续遍历下一个人
print("下船的人员列表:",lst2)


-------------------------------------------------------

lst1 = list(range(1, 31))
lst2 = []
print("船上人员为",lst1)
while len(lst1) > 20:
    index = 7
    lst3 = lst1.pop(index)
    lst2.append(lst3)
print("下船的人员列表:")
print(lst2)


python集合


#1、有序项目集合
#2、可以存放任何数据类型对象
#3、不可变数据类型

#定义 --- tuple  类型转换函数 将其他可迭代对象转换成元组
t1 = ()
print(type(t1))
t1 = (1,)  #只有一个元素的时候,在后面添加逗号,区分是元组还是结合运算
print(type(t1))
t2 = tuple("abc")
t3 = tuple(["a","bb","c"])
print(t2,t3)

#元组是不可变
print(t2[0])
t2[0] = "xxx"

#元组中存放可变数据类型元素的时候,那这个元素是可以改变的
t1 = ("abc",3,[1,2],8.5)
print(t1[2])
t1[2].append(3)
print(t1)

#----dict 字典
#1、 键值映射的数据结构  key-value 类似go map
#2、 无序项目集合 -- 没有下标索引
#3、 可变数据类型

#字典底层存储 -- 哈希表

#字典的key  -- 天生去重
#key必须是可hash对象 -- 不可变数据类型

#字典的定义
d1 = {
    "name":"root"."passwd":"123456"}

#字典的取值
print(d1["name"])
print(d1["xxx"])  #如果不存在这个key,会抛出异常
print("end.......")

#使用get属性取值 -- 推荐
print(  d1.get("name"))
print(  d1.get("xxx"))   #没获得取值,不会报错,默认返回None
print(  d1.get("xxx",100)) #获取到xxx的值就返回,没有就返回100
#遍历
d1 = {
    "x":1,"y":2,"z":3}

for i in d1: #遍历key
    print(i)

for i in d1.items(): #key value 一起遍历返回元组
    print(i)

for k,v in d1.items():
    print(f"{
      k}-->{
      v}")
#成员关系判断 -- 判断key
d1 = {
    "x":1,"y":2,"z":3}
print("x"in d1)
print(1 in d1)
print(d1.values())
print(1 in d1.values())

#字典的删除操作
1dict.pop()  删除指定key
2dict.popitem()   删除最后一组key-value

d1 = {
    "x":10, "y":20, "z":30}
result = d1.pop("x")
print(d1, result)

r2 = d1.popitem()
print(d1, r2)

两个字典的合并
d2 = {
    "a":1, "b":2}
d1.update(d2) #把d2的字典内容放到d1里面来
print(d1)

两个字典拼接   -- 不支持加法  -- 使用dict函数
d3 = {
    "name":"admin", "passwd":"123456"}
d4 = d2 + d3
print(d4)
#两个字典合并,生成新字典
d1 = {
    "x":1,"y":2}
d2 = {
    "a":10,"b":20}
d3 = dict(d1,**d2)
print(d3)

#json  轻量级数据交换格式
import json
#dict --> str
d1 = {
    "name":"root","passwd":"123456"}
d1_str = json.dupms(d1)
print(type(d1_str),d1_str)

#str --> dict
d2_str = r'{"x":10,"y":20}'
d2 = json.load(d2_str)
print(type(d2))
print(d2)
集合可以看做是一个只有key的字典  -- set

#无序项目集合
#可变数据类型
#天生去重
#元素必须是可hash对象

#python中可变数据类型是什么意思? 哪些数据类型是可变的 哪些数据类型是不可变的
# 可变数据类型是指可以修改其值的数据类型,而不可变数据类型是指不能修改其值的数据类型。
# 以下是一些常见的可变数据类型:列表、字典、集合
# 以下是一些常见的不可变数据类型:数字、 字符串、元组
# 可变数据类型可以通过添加、删除、修改元素来改变其值,而不可变数据类型的值不能被改变。这意味着对不可变数据类型的操作将会创建一个新的对象,而不是修改原始对象。
#python中list和tuple有什么区别?list和set有什么区别?
# List和Tuple的区别:
# 可变性:List是可变的,即可以修改、添加和删除元素。Tuple是不可变的,一旦创建就无法修改。
# 语法:List使用方括号([])来表示,而Tuple使用圆括号(())来表示。
# 使用场景:List适用于需要频繁修改数据的情况,而Tuple适用于不需要修改数据、只需要读取数据的情况。另外,Tuple在函数返回多个值时很常用。
# List和Set的区别:
# 重复元素:List允许元素重复,而Set不允许有重复元素,每个元素在Set中是唯一的。
# 顺序性:List是有序的,即元素的顺序是根据插入的顺序来确定的。Set是无序的,即元素没有固定的顺序。
# 存储方式:List是通过索引来访问元素,而Set是通过集合运算(如交集、并集)来访问元素。
# 使用场景:List适用于需要保留元素的顺序和允许重复元素的场景。Set适用于需要快速查找和去重的场景,对于不关心元素顺序的情况下,Set具有较高的查找效率


#集合的定义 -- set 接收可迭代对象  容器类型都是可迭代对象
s1 = {
    1,2,3}
s2 = set
print(type[s1],type[s2])
s3 = set("aaabbbcc")
print(s3)

# s4 ={[1,2],121} 不能存放可变数据类型
# print(s4)

#集合  添加、删除元素
s1 = {
    1,2,3}
s1.add(4)
print(s1)

s1.update("abc") #传递可迭代对象
print(s1)

s1.remove("c") #没有找到要删除的元素,会抛出异常
print(s1)

s1.discard("b") #删除元素,没有找到不会报错
print(s1)

#集合的运算
s1 = {
    1,2,3}
s2 = {
    2,3,4}
print(s1 & s2)
print(s1 | s2)
print(s1 - s2)
print(s1 ^ s2)

#类型转换
lst = ["aa","bb","cc","dd"]
str1 ="aabbcc"
print(list(str1))
print(set(lst))

tuple1 = (("a",1),("b",2))
d1 = dict(tuple1)
print(d1)
#判断文件是否存在
#某个目录下有哪些文件 -- os

# 文件读写操作  ---open 函数
#打开的文件句柄
fp = open("test.txt")
#默认只读方式打开
print(fp.read())
print("############")
print(fp.read())

#对文件进行操作 -- 关心文件指针(光标),对文件所有操作都是在文件指针之后进行
fp.week(0)#将光标置于文件初始位置
print(fp.read())

# 读取方式 -- fp.read()    fp.readline()  fp.readlines()
fp.seek()
print( fp.read(2)) # read默认从开头读到结尾,可以传入一个整形数据,表示一次性读取几个字节
print(fp.readline()) #从光标的位置开始读取,每一次读取一行内容
print(fp.readlines()) #从光标的位置默认读到文件末尾,每一行作为一个元素存放列表中返回


#文件编码
fp = open("test.txt",encording = "gbk")
print(fp.read())

#文件打开方式 -- 第二个参数
fp = open("test.txt","r")
#r -- read  w --write(覆盖写)  a--append(追加写)  x -- 新建
#读写 r+ w+ a+
#写缓存和读缓存
import  time
with open("test2.txt"."w")  as  fp:
    fp.write("hello world!")
    print("写入完成...")
    time.sleep(60)
    
#什么时候写入磁盘?
# 1 缓冲区满了
# 2 文件关闭
# 3 fp.flush()
# 4 程序结束

python常用模块

如何学习模块?

"""
模块:
导入os 的模块
import os

指令条件语句:if 
函数:print

模块:python 的文件
模块的分类:
    内置模块 : 不需要安装直接就能使用的模块  (打包在安装程序中)
    三方模块 : 需要安装的模块,别人写好了的
    自定义模块: 我们自己写的模块()
    
如何去学习一个模块:
1、了解模块的基本信息
    平台支持信息  python2/python3/windows/linux  版本兼容性
    https://pypi.org/
    pip install 模块名
    
2.安装
    源码安装:不建议
    pip install 模块名  默认安装最新版本

3.了解支持哪些方法和属性
    利用pycharm的提示功能
    dir =>查看对象有哪些属性或方法
    help ==>查看对象(函数)的帮助信息
    
4.实践(案例)

5.遇到问题怎么办
上网,文心一言,老师和同学
    

"""
import os
# f ==>function ==>函数 ==> 实现某一个功能的代码 ==》函数名()来调用它
print(os.cpu_count())
# v ==>value ==>属性(变量,子模块)
print(os.path)
#print(os.path.dirname())

print(dir(os))
help(os.path.dirname)
print(os.path.dirname("/root/a.txt"))  # 输出结果 /root 返回文件的根目录

help(print)
help(dir)

模块ipaddress

#命名时注意文件名不与模块重名
import ipaddress

#ipaddress 系统标准库(内置模块)

# 查看是干什么的(在help最前面)
#help(ipaddress)

# 查看有什么功能
print(dir(ipaddress))
#查看指定函数的帮助信息
help(ipaddress.ip_address)

#ip 地址是可以转换成一个int类型的数据的
#  int类型的数据可以转换成ip地址的  ==》 数据库中存储的时候可能会这样用
#string => 114.114.114.114 ===>len:15
#int ==>len:4
# result=ipaddress.ip_network("192.168.1.1")
# print(result,type(result))

#result2= ipaddress.ip_network("192.168.1.2/24")
#print(result2,type(result2))
#print(result in result2)

# callapse_addresses /v4_int_to_packed ==> 自己查看是什么功能,测试一下

WHITE_HOST = ["192.168.1.0/24","192.168.2.0/24"]

# 用户输入一个ip地址,如果IP地址是在白名单中,就输出”欢迎光临“
# 不在白名单中,输入”非法访问“

"""
1.接收数据
2.判断数据是否合法:string/ing =>正则表达式re模块
3.如果合法,转换成ip_address类型,如果不合法,提示并退出

"""
ip = ipaddress.ip_network(input("请输入一个ip地址"))
for network in WHITE_HOST:
    if ip in ipaddress.ip_network(network):
        print("欢迎光临")
        break
    else:
        print("非法访问")

模块os

import os
print(dir(os))
print(dir(os.path))

#判断指定的路径是否存在
print("判断路径是否存在:",os.path.exists("C:\\a.txt"))
print("判断路径是否存在:",os.path.exists("C:\\"))

# 如果目录存在,忽略,目录不存在 创建一个目录
if not os.path.exists("./download"):
    os.mkdir("./download")

#检查是否为一个文件
print("判断被指定的对象是否为一个文件:",os.path.isfile("./a.txt"))
print("判断被指定的对象是否为一个文件:",os.path.isfile("./练习题.txt"))

# 检查是否为一个目录
print("判断指定的对象是否欸一个目录:",os.path.isdir("./download"))
print("判断指定的对象是否欸一个目录:",os.path.isdir("./练习题.txt"))
# 列出指定路径下的所有文件和目录
print("查看指定目录下所有文件和目录:",os.listdir("./"))
print("查看指定目录下所有文件和目录:",os.listdir("E:\\"))

# 如何分离文件名和后缀名




# 判断当前(指定目录下)各种类型的文件有多少个
dir1 = os.listdir("E:\\")
count_file = 0
count_list = 0
for dir in dir1:
    if os.path.isfile(os.path.join("E:\\", dir)):
        count_file +=1
    if os.path.isdir(os.path.join("E:\\", dir)):
        count_list +=1
print(count_file)
print(count_list)

all_files = os.listdir()
print(all_files)

模块psutil

#!/usr/bin/env python
# @FileName :模块-psutil.py
# @Time :2024/3/3 14:59
# @Author :huya
import time

import psutil
# print(dir(psutil))
# #help(psutil.cpu_count)
#
# print("逻辑cpu的个数是:",psutil.cpu_count())
# print("物理cpu的个数是:",psutil.cpu_count(logical=False))
#
#print(dir(psutil))
#
# #interval  ==> 等n 秒之后输出结果
# #percpu ==>是否为每个cpu输出百分比
# help(psutil.cpu_percent())
# print(psutil.cpu_percent(percpu=True))
# print(psutil.cpu_percent(interval=5,percpu=True))

# 输出
# 1磁盘分区信息及其使用率
# 分区名 文件系统格式  参数
print("磁盘分区信息:",psutil.disk_partitions())

for item in psutil.disk_partitions():
    print(item.device,'\t',item.fstype,'\t',item.opts)

disk_c = psutil.disk_usage(path="C:\\")
print("c盘使用率情况:",disk_c.total,disk_c.used,disk_c.free,disk_c.percent)
# 2.磁盘IO信息
print("磁盘IO信息",psutil.disk_io_counters())

# 3.输出所有系统进程信息
# print("所有的pid信息",psutil.pids())
# for pid in psutil.pids():
#     print(psutil.Process(pid).name())

# 4.输出当前登录的用户信息
print(psutil.users())


#help(psutil.cpu_percent())
#help(psutil.cpu_count())




def print_disk_partitions_and_usage():
    disk_partitions = psutil.disk_partitions()
    for partition in disk_partitions:
        usage = psutil.disk_usage(partition.mountpoint)
        print(f"分区: {partition.device}")
        print(f"挂载点: {partition.mountpoint}")
        print(f"总空间: {usage.total / (1024 ** 3)} GB")
        print(f"已使用: {usage.used / (1024 ** 3)} GB")
        print(f"可用空间: {usage.free / (1024 ** 3)} GB")
        print(f"使用率: {usage.percent}%")
        print("---")


def print_disk_io_info():
    io_counters_start = psutil.disk_io_counters()
    time.sleep(1)  # 等待1秒
    io_counters_end = psutil.disk_io_counters()

    read_per_second = (io_counters_end.read_bytes - io_counters_start.read_bytes) / 1024 ** 3
    write_per_second = (io_counters_end.write_bytes - io_counters_start.write_bytes) / 1024 ** 3

    print(f"每秒读取速度: {read_per_second:.2f} GB/s")
    print(f"每秒写入速度: {write_per_second:.2f} GB/s")


#print_disk_io_info()

print("=======")

#print_disk_partitions_and_usage()

练习

# 输出:
# 1. 输出磁盘分区信息及使用率
# 分区名   文件系统格式      参数
print("磁盘分区信息:", psutil.disk_partitions())
for item in psutil.disk_partitions():
    print(item.device,'\t', item.fstype, '\t', item.opts)

disk_c = psutil.disk_usage(path="C:\\")
print("C盘使用率情况:", disk_c.total, disk_c.used, disk_c.free, disk_c.percent)

# 2. 输出磁盘IO信息
print("磁盘IO信息:", psutil.disk_io_counters())

# 3. 输出所有系统进程信息
# print("所有的pid信息:", psutil.pids())
# for pid in psutil.pids():
#     print(psutil.Process(pid))

# generator object => 生成器(迭代器) => 写好计算方法 =>
print(psutil.process_iter())

for proc in psutil.process_iter():
    print(proc.name())
    # proc.as_dict()


# 4. 输出当前登录的用户信息
print(psutil.users())

显示当前目录下单个文件的大小,及目录大小
输入后缀名和文件前缀,将指定类型的文件加上统一前缀
输入文件名和搜索的目录,将找到的文件路径输出

爬虫核心

爬虫核心:

爬取网页:

解析数据:

存储数据:

分析数据:

难点:爬虫和反爬虫之间的博弈;

​ 爬虫会加大系统负载:并发(每秒访问的人数100) 爬虫1000

​ 什么是反爬虫?

​ 阻止非正常用户来访问我的系统

​ 登录站点:==》获取验证码(图片,手机)

​ 刷新太快请稍后重试

反爬虫手段;

1.robots 协议(www.baidu.com/rebots.txt)

约束性: Robots 协议是建议但并非约束性,网络爬虫可以不遵守,但存在法律风险

作用:网站告知爬虫哪些页面就可以爬取,哪些不能爬取

2.检查User-Agent

·User Agent中文名为用户代理,简称UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及
版本、CPU类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
。网站可以通过检查该字段判断是否为浏览器

解决方法:
。可以自己设置一下user-agent,或者更好的是,可以从一系列的user-agent里随机挑出一个符合标准的使用。

  1. ip 限制

如果一个固定的ip在短暂的时间内,快速大量的访问一个网站,后台管理员可以编写IP限制,不让该IP继续访问。
。1s钟内10次 =>把ip放入黑名单,禁止在1h(5min)内访问
o nginx/other…
。解决方法:

。比较成熟的方式是:IP代理池
。降低访问频率(time.sleep(2))

4.session 访问限制

后台统计登录用户的操作,比如短时间的点击事件,请求数据事件,与正常值比对,用于区分用户是否处理异常状态,如果是,则限制登录用户操作权限。
·解决方法:
。注册多个账号、模拟正常操作。

  1. 验证码

    验证码是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式
    解决方法:
    。接入第三方验证码平台,实时破解网站的验证码

  2. 数据动态加载

    python的requests库只能爬取静态页面,爬取不了动态加载的页面。使用!S加载数据方式,能提高爬虫门槛。
    。解决方法:
    。抓包获取数据url
    oselenium 驱动真实的浏览器发送请求

  3. 数据加密-使用加密算法

前端加密 通过对查询参数、user-agent、验证码、cookie等前端数据进行加密生成一串加密指令,将加密指令作为参数,再进行服务器数据请求。该加密参数为空或者错误,服务器都不对请求进行响应。
·解决方法
。JS加密破解方式,就是要找到S的加密代码进行破解。

参数介绍 位置参数 关键字参数

在这里插入图片描述

#!/usr/bin/env python
# @FileName :request模块.py
# @Time :2024/3/10 10:19
# @Author :huya

import requests

#print(dir(requests))
help(requests.get)

#
#括号中的叫函数的参数
"""
get(url,params=Nome,)
url         ==> 位置参数==》必选参数(有顺序,按位置依次给数据)注意按顺序传递参数 第一个是url
params      ==> 默认参数 如果你没有传递会给一个默认值
*args       ==> 可变长位置参数  接收多个(位置)参数
**kwargs    ==> 可变长关键字参数 => 接收多个(关键字)参数

#实现一个mysum函数,可以接受多个数据,计算这个数据的和
"""
def mysum2(*args,**kwargs)->int:
    """
    计算出所有传进来的数据的和
    :param args:
    :param kwargs:
    :return:
    """
    print("args:",args)
    print("kwargs:",kwargs)

    sum =0
    for arg1 in args:
        sum += arg1
    for kwarg1 in kwargs:
        sum += kwargs[kwarg1]
    return sum
print(mysum2(1,2,3,4 ,a=1,b=2,c=3))
#注意:SyntaxError: positional argument follows keyword argument
#位置参数要在关键字参数前面
#mysum2(1,2 ,a=1,b=2,c=3,3,4)


print("==============")
#调用: requests。get("test","http://www.baidu.com")  test 会给url  http给params  会按位置  错误
#调用: requests。get(params="test",url="http://www.baidu.com")                          正确

# def 函数名(参数列表<0-n>):
#        函数体
#       return value ==>返回值
def mysum(a,b):
    return a+b
a=1
b=2
#位置参数的调用
#print(mysum(a,b))
#关键字参数的调用
#print(mysum(b=1,a=2))

#mysum(1)
#TypeError: mysum() missing 1 required positional argument: 'b'

# 定义一个函数实现 华氏度=32+摄氏度×1.8
# 如果没有传参数过来,就将 0 作为参数

def convert_temperature (Celsius:int=0) ->float:
    """

    :param Celsius: 传递一个int类型的摄氏温度
    :return: float
    """
    return Celsius * 1.8 +32

print(convert_temperature())







#参数名:数据类型 ==》 告诉调用着,该函数需要是什么类型的
#              ==> 类型声明是可写可不写的
# 设置默认参数 Celsius:int=0
# 推荐写法
"""
def convert_temperature (Celsius =None) ->float:
    if Celsius is None:
        Celsius = 0
    return Celsius * 1.8 +32

print(convert_temperature())
"""




# -> 数据类型    ==》函数的返回值
#return 接返回值  ==》函数如果没有return 语句,表示返回None
#文档注释(doucument strint)和类型注解(type hint)都是可选的  传递时可以不按照注解 非强制性的
def ctof(celsius:int) ->float:
    """
    :param celsius: 传递一个int类型的摄氏温度
    :return: 返回一个float类型的华氏温度

    """

    # pass ==>占位符 ==》什么也不做 ==> 保持语法完整
    pass
    return 32+celsius*1.8

print(ctof(10))

requests 模块核心

#!/usr/bin/env python
# @FileName :2.requests模块.py
# @Time :2024/3/10 15:22
# @Author :wenyao

# requests模块功能
# 相当于一个模块浏览器,发送网络请求,获取数据

import requests
# 获取百度首页的数据
url="http://www.baidu.com"
response = requests.get(url)
print(response, type(response))
# status_code => 200 OK
#             => 用代码的方式告诉你,你的请求是否正确
#             =>2XX 成功
#             =>4XX 客户端错误
#             =>5XX 服务端错误
#             => $? => 0 成功,其他错误
# 取出当前响应的状态码
print(response.status_code)
# 获取当前的网页数据
# text => string
print(response.text[:100])
# content  => bytes
print(response.content[:100])
# 获取请求的url
print(response.url)
# 获取响应头信息
print(response.headers)
print(dir(response))
# 获取编码方式   UTF8(全球),GBK(中文)
print(response.encoding)
# 推荐!
print(response.apparent_encoding)

python函数


import requests
# get(url ,params=None,**kwargs)

"""
def 函数名(位置参数:数据类型,默认参数:数据类型=默认值,可变长位置参数,可变长关键字参数)
    pass
    return 返回值
def function(a:int,b:int=0,*args,**kwargs) -> int:
    pass
    return a
如果函数没有返回值,相当于返回None
"""

def sum(*args,**kwargs) -> int:
    #args ==>保存的是:调用时传过来的位置参数
    #kwargs ==> 保存调用时传的所有的关键字参数
    print(args)# typle
    print(kwargs) # dict
    s = 0
    for i in args:
        s+=i
    for kev in kwargs:
        s+=kwargs[kev]
    return s

# 什么时候需要套用return  ==>   如果算出来的结果还有其他用途

print(sum(1,2,3,4,a=1,b=2))

"""
1.函数定义参数的类型 4 类 (注意顺序)
2.函数调用参数类型2 类
3.注释:文档注释(写的一些帮助信息 ->help 时可以看到),类型注解和返回值做类型声明)
            类型注解在高版本中是否有强制类型限制?自己试试
4.返回值:return => 如果还需要用到(一般情况建议返回)

        

"""
help(requests.get)

bs模块

#!/usr/bin/env python
# @FileName :4.bs模块.py
# @Time :2024/3/17 10:25
# @Author :huya
from bs4 import BeautifulSoup



# file ==> string  ==>  要打开文件的位置
# mode ==> string  ==>  打开文件的模式
#           读r  ==》 文件不存在会报错
#           写w  w=>  先覆盖文件的内容,如果文件不存在,会创建按一个新的空文件
#           可读写 r+ 或 w+
#           二进制模式:b  ==>这种模式,不需要写文件的编码方式   (在磁盘上是什么样子就直接怎样打开,不要转码)
#           文本模式(encoding 用于设定打开方式):默认就是文本模式,需要传参文件编码方式  (如果没有声明,用默认编码方式打开,有可能乱码出错)

# 读取html文件
#file = open("./demo.html","rb",encoding="utf-8")
file = open("./demo.html","rb")
#print(file.read())
html = file.read()

#解析成bs 对象
#参数1:要解析的html文件内容
#参数2:解析方式(python 标准库,lxml)
bs = BeautifulSoup(html,"lxml")
print(bs)
print(type(bs))
#查看有缩进的效果
print(bs.prettify())

#1. 获取第一个匹配的数据
print("1",bs.title,type(bs.title))
print("2",bs.body)
print("3",bs.body.div)
print("4",bs.head.meta)

#获取标签的内容
print("5",bs.head.title.string)
print("5",bs.head.title.get_text)
print("5",bs.head.title.string)
#如果标签中的日容为空
# string ==> None,get_text(),text ==>空字符串
#如果标签中嵌套标签,且多个标签中有文本
# sting ==>None,get_text(),text => 会去除标签,合并所有文本

# 获取标签的属性值
print("6",bs.div["id"]) #6 wrapper
print("6",bs.div.get("id"))  #6 wrapper
print("6",bs.div.attrs) # 获取字典中所有的属性 6 {'id': 'wrapper'}

#<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻<span>abc</span></a>
#获取第一个a标签的id 和 href 属性
#print(bs.a["id"],bs.a.get("href"))  #报错  return self.attrs[key]  KeyError: 'id'
print(bs.a.get("id"),bs.a.get("href"))  #None http://news.baidu.com

# 修改数据
bs.a["class"] = "test_mnav"
print(bs.a)
bs.a["id"] = "a1"
print(bs.a)

# 获取所有匹配的数据

# bs.find_all(标签名,attrs={},**kwargs)
# 获取所有a标签
a_list = bs.find_all("a")
print("8",a_list,len(a_list))

# 打印所有的 a 标签的href 属性
for tag in a_list:
    print(tag.get("href"))

# 获取所有的a 标签和meta 标签
a_list= bs.find_all(["a","meta"])
print("9",a_list,len(a_list))

# 查找所有name 属性的标签
def has_name(tag):  # 查找所有的包含name 标签的内容返回
    return tag.has_attr("name")


a_list = bs.find_all(has_name)    #将函数返回的内容放入列表中
print("10",a_list,len(a_list))

# 查找所有class="mnav" 的标签
# class 是一个python的关键字
# data-foo 也是一个不合法的变量名
#a_list = bs.find_all(class="mnav")  会报错
a_list = bs.find_all(attrs={"class":"mnav"})
print(11,a_list,len(a_list))

a_list = bs.find_all(id="u1") # 方式1
print(12,a_list,len(a_list))
a_list = bs.find_all(attrs={"id":"u1"})  # 方式2  兼容性强一些
print(12,a_list,len(a_list))

# 匹配标签内容中含test,返回一个文本列表
# 一般string 参数后面使用正则,==》讲完正则后补
a_list = bs.find_all(string="test")
print(a_list,len(a_list))

import re
a_list = bs.find_all(string=re.compile("test"))
print(a_list,len(a_list))

# 查找所有的a 标签
a_list = bs.find_all("a")
print("12",a_list,len(a_list))
a_list = bs("a")
print("12",a_list,len(a_list))
# 查找第一个匹配到的a 标签
a_list = bs.a(text="新闻")
print(a_list,len(a_list))

#返回第一个匹配到的数据
# find_all返回一个列表
# find返回一个标签
#说有用法与find_all 一致,相当于制定了一个limit =1 的参数
bs.find()

a_list = bs.find_all("a",limit=1)
print("12",a_list,len(a_list))

# 练习

# 查找name="tj-trvideo“ 的标签
a_list = bs.find_all(attrs={"name":"tj_trvideo"})
print("13",a_list,len(a_list))

# 返回id = u1 这个div 下所有的a 标签
a_list = bs.find(attrs={"id":"u1"}).find_all("a")   # 法1
print("14",a_list,len(a_list))

a_list = bs.find(attrs={"id":"u1"})("a") #法2 省略find_all
print("14",a_list,len(a_list))

lxml.xpath 模块

#!/usr/bin/env python
# @FileName :5.lxml.xpath模块.py.py
# @Time :2024/3/23 10:12
# @Author :huya

from lxml import html

# 读取html 文件

file = open("demo.html", "rb")

#html = file.read()

# 讲文本(string/bytes) 转换成python 对象
root_elment = html.fromstring(file.read())
print(root_elment,type(root_elment))
# HtmlElement
# root_element ==>html

# 提取数据
"""
//标签[@属性名=“属性值”]/标签[@属性名=“属性值”]/text()
//标签[@属性名=“属性值”]/标签[@属性名=“属性值”]/@属性名
//div[@id="head"]/a
"""

# /nodename: 从根节点开始选取子节点
#查找所有div 的子节点
content = root_elment.xpath("/div")
print(content,len(content))

# /nodename:  从根节点开始选取子孙节点
#查找所有div 的子孙节点
content = root_elment.xpath("//div")
print(content,len(content))

#.. 查找父节点
print(content[0],content[0].xpath(".."))
print(content[1],content[1].xpath(".."))
#.  查找当前节点
print(content[1],content[1].xpath("."))

### //
### ./

# 注意/ 和 // 是从根开始查找  .和.. 是从当前路径开始查找

result = content[0].xpath("/html")
print(result)

result = content[0].xpath("./html")
print(result)

# 查找所有class = mnav 的a 标签
content=root_elment.xpath('.//a[@class="mnav"]')
print(content,len(content))

# 查找class="foot"  这个div 下的所有的a标签
content=root_elment.xpath('.//div[@class="foot"]/a')
print(content,len(content))
# a[1] 表示第一个获取到的数据
content=root_elment.xpath('.//div[@class="foot"]//a[1]/@href')
print(content,len(content))

# .//相当于find_all


爬取豆瓣图书top250 实例

#!/usr/bin/env python
# @FileName :3.豆瓣读书top250.py
# @Time :2024/3/10 16:21
# @Author :huya
import requests
import time


#定义一个download,参数是要获取的url  返回值网页string 类型的数据


def download(url:str) ->str:
    """
    这个函数用来获取url 的数据,返回网页的string
    :param url:应该提供一个网址
    :return: 返回网页的str类型的数据
    """
    # 反爬虫1 添加user-agent
    headers = {
       "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"
    }

    response = requests.get(url,headers=headers)

    #如果获取网页失败,或者获取到网页了但是状态码不对,那么请报异常
    # 404 not found ,5XX 都会抛出异常
    # raise 关键字  ==》 抛出异常
    response.raise_for_status()

    # 指定正确的网页的编码
    response.encoding = response.apparent_encoding


    # 反爬虫2 添加sleep
    time.sleep(1)

    return response.text


def download_img(url: str) -> bytes:
    """
    这个函数数用来获取url的数据,返回网页的string
    :param url: 应该提供一个网址
    :return: 返回网页的string类型的数据
    """
    # 反爬虫1:添加user-agent
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
    }
    response = requests.get(url, headers=headers)

    # 如果没有获取到网页或者获取到网页了,但状态码不对,那么请报异常
    # 4xx , 5xx 都会抛出异常
    # raise关键字 => 抛出异常
    response.raise_for_status()

    # 指定正确的网页编码
    # response.encoding = response.apparent_encoding

    # 反爬虫2:增加sleep
    time.sleep(1)
    return response.content


# 1.获取数据
data = (download("https://book.douban.com/top250"))
# 2.提取数据
# re 模块 :正则表达式:速度最快 使用难度最高
# lxml(xpath): 速度最快,使用难度一般
# BeautifulSoup :慢 ,最简单


# 项目正式开始:===


from bs4 import BeautifulSoup
bs = BeautifulSoup(data,"lxml")
"""
一旦你有了bs对象,你就可以使用它的各种方法和属性来提取
和操作HTML或XML数据了。例如,你可以使用find、find_all、select
等方法来定位特定的标签或元素,并提取其属性、文本内容等。
"""

import os
#判断目录是否存在,如果不存在就创建目录
path = "douban_imgs"
if not os.path.exists("douban_imgs"):
    os.mkdir(path)


# 最重要的步骤就是要分析页面!!!

base_url = "https://book.douban.com/top250?start="
count = 1  #用于计数

for i in range(10):
    url = base_url+str(i*25)  # 字符串拼接 由于网站要翻页 根据实际情况
    # url = "{base_url}{n}".format(base_url=base_url, n=i*25)
    # url = f"{base_url}{i*25}"
    print(url)
    data = download(url)    获取数据

    # 用bs 解析数据
    from bs4 import BeautifulSoup
    bs = BeautifulSoup(data, "lxml")  #获取bs对象

    # 所有书本信息
    # all_book = bs.find_all("table")
    all_book = bs.find(attrs={"id":"content"}).find_all("table")
	#        这里用find  写个find_all你找了20分钟

    for book in all_book:
        # print(book)
        # print(book.img)
        book_cover = book.img["src"]
        print(book_cover)

        # "" .join(内容.split)  使用空白字符切割 可去除中间的空格
        """ 注释
        [1] 这是下标 代表取第二个a
        .strip()  去除前后空白
        """
        # 提取书名
        book_title = "".join(book.find_all("a")[1].text.strip().split())
        book_title = book_title.replace(":",":")   # 将英文: 替换成中文:
        print(book_title)
		
		#提取评分
        book_rate = book.find(attrs={"class":"rating_nums"}).text
        print(book_rate)

        # 保存图片,count.book_title.jpg
        book_cover_path = f"{path}/{count}.{book_title}.jpg"

		# 打开文件
        file = open(book_cover_path,"wb") 
		
		# 写文件
        file.write(download_img(book_cover))
        # 关闭文件
        file.close()
        
		# 计数器
        count+=1

熟悉爬虫项目练习:

注册:https://www.heywhale.com/
思考:想一个自己想爬取的网站(有比较多的数据,抓取的数据分析一些什么内容,可视化)

招聘信息爬取与分析
爬取各大招聘网站(如BOSS直聘、前程无忧、智联招聘等)的职位信息。
分析热门职位、薪资水平、学历要求等,为求职者提供职业发展规划参考。
可以进一步开发可视化工具,展示分析结果。


招聘信息爬取与分析系统

项目背景与目的:

随着互联网的普及,越来越多的求职者选择在线查找和申请工作。各大招聘网站如BOSS直聘、前程无忧、智联招聘等汇聚了海量的职位信息。然而,对于求职者来说,手动浏览和分析这些信息既耗时又低效。因此,开发一个能够自动爬取并分析招聘信息的系统,为求职者提供职业发展规划参考,具有重要的实用价值。

项目内容:

数据爬取:
选定目标招聘网站,如BOSS直聘、前程无忧、智联招聘等。
设计并编写爬虫程序,自动爬取各网站上的职位信息,包括职位名称、薪资水平、学历要求、工作经验要求、工作地点等。
将爬取到的数据存储到数据库中,以便后续分析和处理。
数据清洗与整合:
对爬取到的原始数据进行清洗,去除重复、错误或无效的信息。
对清洗后的数据进行整合,形成统一的数据格式,方便后续的分析和可视化。
招聘信息分析:
分析热门职位的分布情况,包括职位数量、竞争程度等。
分析薪资水平,比较不同职位、不同地区的薪资差异。
分析学历要求和工作经验要求,了解不同职位的入职门槛。
可视化展示:
开发可视化工具,将分析结果以图表、地图等形式展示出来。
允许用户根据职位、地区等条件进行筛选和查询,获取个性化的分析结果。
技术难点与解决方案:

技术难点:
应对反爬虫机制:部分招聘网站可能设置了反爬虫机制,需要采用合适的策略来绕过这些限制。
大数据处理:招聘信息数量庞大,需要高效的数据处理和存储方案。
解决方案:
使用代理IP、调整请求频率等方式来应对反爬虫机制。
采用分布式爬虫架构,提高数据爬取的效率。
使用数据库和缓存技术来存储和处理数据。
项目成果与展示:

将项目成果托管到GitHub等代码托管平台,并附上详细的项目文档和使用说明。
制作一个演示视频或PPT,展示系统的功能、分析结果以及可视化效果。
在简历中突出展示该项目的创新点、技术难点及实现成果,吸引招聘者的关注。
通过这个项目,你能够展示你的爬虫技术、数据分析和可视化能力,同时体现出你对招聘市场的理解和洞察。这样的项目在简历中不仅具有亮点,还能为你的求职增色不少。


参考:

  • 第七次人口普查数据分析可视化: https://www.heywhale.com/mw/project/659bb732f4a4c0307bf9bf94
  • Python爬虫+数据分析可视化中国影院票房:https://www.heywhale.com/mw/project/65758b6535cd36646b388824
  • 蜜雪冰城全国门店数据分布:https://www.heywhale.com/mw/project/65911eb9ced1f8ff72f129c5
  • 基于pycharts对北上广深天气数据进行可视化分析: https://www.heywhale.com/mw/project/64d359f13af70a72062d57f9

1.梳理今天学的 函数内容和爬虫内容

课后练习

练习1:豆瓣Top250爬虫

  • 打印书的基本信息(book_info)

  • 给图片加上书的排名

练习2:爬取彼岸图网图片

  • 入口网址:https://pic.netbian.com/
  • 将图片保存到本地
  • 用xpath、bs、re选择一种即可(也可以全部试一试)
  • 代码:1-ex.get_pic.py

作业:注册腾讯云服务,完成实名认证

https://console.cloud.tencent.com/

  • 注册腾讯云服务
  • 完成实名认证
  • 开通服务

https://console.cloud.tencent.com/cos

1.创建存储桶

2.配置 设置CORS 规则

3.创建API密钥

保存好密钥:

SecretId:AKIDIUZRAwb4Jb3TnT7qRq0wlLhpiPt9JI3o
SecretKey:mU6eH4qgXbWIzWuMupaCqP3TeaQLAqgN

官方文档

https://cloud.tencent.com/document/product/436

https://cloud.tencent.com/document/product/436/65820

云服务器上传文件示例

#!/usr/bin/env python
# @FileName :6.tencent-cos.py
# @Time :2024/3/24 10:23
# @Author :huya

#pip install -U cos-python-sdk-v5


# 复制的代码
# -*- coding=utf-8
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
from qcloud_cos.cos_exception import CosClientError, CosServiceError
import sys
import os
import logging

# 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息
logging.basicConfig(level=logging.INFO, stream=sys.stdout)

# 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成
secret_id = "AKIDIUZRAwb4Jb3TnT7qRq0wlLhpiPt9JI3o"    # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
secret_key = "mU6eH4qgXbWIzWuMupaCqP3TeaQLAqgN"   # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
region = 'ap-shanghai'      # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
                           # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224
token = None               # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048
scheme = 'https'           # 指定使用 http/https 协议来访问 COS,默认为 https,可不填

config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
client = CosS3Client(config)

bucket='huya-jiayou-1325249148'

# 使用高级接口上传一次,不重试,此时没有使用断点续传的功能
response = client.upload_file(
    Bucket=bucket,
    Key='红楼梦999.jpg',
    LocalFilePath='douban_top250_imgs/1.红楼梦.jpg',
    EnableMD5=False,
    progress_callback=None
)

# 获取刚刚上传的图片的地址
url = f"{scheme}://{bucket}.cos.{region}.myqcloud.com/红楼梦.jpg"

7.豆瓣读书TOP520-cos

#!/usr/bin/env python
# @FileName :7.豆瓣读书TOP520-cos.py
# @Time :2024/3/24 11:51
# @Author :huya

#!/usr/bin/env python
# @FileName :3.豆瓣读书top250__bs.py
# @Time :2024/3/10 16:21
# @Author :huya
import requests
import time
from tencent_cos import upload


#定义一个download,参数是要获取的url  返回值网页string 类型的数据


def download(url:str) ->str:
    """
    这个函数用来获取url 的数据,返回网页的string

    :param url:
    :return: 返回网页的str类型的数据
    """
    # 反爬虫1 添加user-agent
    headers = {
       "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"
    }


    response = requests.get(url,headers=headers)


    #如果获取网页失败,或者获取到网页了但是状态码不对,那么请报异常
    # 404 not found ,5XX 都会抛出异常
    # raise 关键字  ==》 抛出异常
    response.raise_for_status()




    # 指定正确的网页的编码
    response.encoding = response.apparent_encoding


    # 反爬虫2 添加sleep
    time.sleep(1)
    return response.text


def download_img(url: str) -> bytes:
    """
    这个函数数用来获取url的数据,返回网页的string
    :param url: 应该提供一个网址
    :return: 返回网页的string类型的数据
    """
    # 反爬虫1:添加user-agent
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
    }
    response = requests.get(url, headers=headers)

    # 如果没有获取到网页或者获取到网页了,但状态码不对,那么请报异常
    # 4xx , 5xx 都会抛出异常
    # raise关键字 => 抛出异常
    response.raise_for_status()

    # 指定正确的网页编码
    # response.encoding = response.apparent_encoding

    # 反爬虫2:增加sleep
    time.sleep(1)
    return response.content


# 1.获取数据
data = (download("https://book.douban.com/top250"))
# 2.提取数据
# re 模块 :正则表达式:速度最快 使用难度最高

# lxml(xpath): 速度最快,使用难度一般
# BeautifulSoup :慢 ,最简单

from bs4 import BeautifulSoup
bs = BeautifulSoup(data,"lxml")
"""
一旦你有了bs对象,你就可以使用它的各种方法和属性来提取
和操作HTML或XML数据了。例如,你可以使用find、find_all、select
等方法来定位特定的标签或元素,并提取其属性、文本内容等。
"""
import os
#判断目录是否存在,如果不存在就创建目录
path = "douban_top250_imgs"
if not os.path.exists("douban_top250_imgs"):
    os.mkdir(path)


import os
from getfile import download, download_img
# csv文件=> 用逗号将字段进行分隔 => 用excel打开的时候,可以像表格一样展示
csv_file = open("douban250.csv","w+",encoding="gbk")

# 添加日志配置,将日志写入到cos.log 文件,INFO
# print ==》 logger.xxxx
# upload ,download ==>加日志的功能(下载了XXX ,上传了XXX)
import  logging
logging.basicConfig(level=logging.INFO,
                    filename="TOP250_cos.log",
                    encoding='utf-8',
                    format="%(asctime)s - %(name)s -%(levelname)s - %(message)s")


# 最重要的步骤就是要分析页面!!!

base_url = "https://book.douban.com/top250?start="
count = 1

for i in range(1):
    url = base_url+str(i*25)
    # url = "{base_url}{n}".format(base_url=base_url, n=i*25)
    # url = f"{base_url}{i*25}"
    logging.info(url)
    data = download(url)

    # 用bs 解析数据
    from bs4 import BeautifulSoup
    bs = BeautifulSoup(data, "lxml")  ##获取bs对象

    # 用lxml 解析数据   (和上面这个bs 效果一样)
    # from lxml import html
    # root_element = html.fromstring(data)


    # 所有书本信息
    all_book = bs.find_all("table")
    all_book = bs.find(attrs={"id":"content"}).find_all("table")
    # all_book =root_element


    for book in all_book:
        # print(book)
        # print(book.img)
        book_cover = book.img["src"]
        logging.info(book_cover)
        print("============")

        # "" .join(内容.split)  使用空白字符切割 可去除中间的空格
        """
        [1] 这是下标 代表取第二个a
        .strip()  去除前后空白
        """
        book_title = "".join(book.find_all("a")[1].text.strip().split())
        book_title = book_title.replace(":",":")   # 英文: 替换成中文:
        logging.info(book_title)

        book_rate = book.find(attrs={"class":"rating_nums"}).text
        logging.info(book_rate)

        # 保存图片,count.book_title.jpg
        book_cover_path = f"{path}/{count}.{book_title}.jpg"

        file = open(book_cover_path,"wb") # 打开文件

        file.write(download_img(book_cover))
        file.close()

        # 添加保存到cos 的功能(封装成一个函数)
        img_url=upload(key=f"{count}.{book_title}.jpg",local_file=book_cover_path)
        logging.info(img_url)
        count+=1

        # 所有的数据保存到csv/excel 文件中
        csv_file.write(f"{img_url},{book_title},{book_rate}\n")
csv_file.close()



封装的模块:

1.getfile

"""
@author: wy
@file: getfile.py
@time: 2024/3/24 11:47
"""

import requests
import time

# def download(url:str) -> str:
#     """
#     这个函数数用来获取url的数据,返回网页的string
#     :param url: 应该提供一个网址
#     :return: 返回网页的string类型的数据
#     """
#     response = requests.get(url)
#     if response.status_code == 200:
#         # 指定正确的网页编码
#         response.encoding = response.apparent_encoding
#         return response.text
#     else:
#         return ""


# try...except
def download(url:str) -> str:
    """
    这个函数数用来获取url的数据,返回网页的string
    :param url: 应该提供一个网址
    :return: 返回网页的string类型的数据
    """
    # 反爬虫1:添加user-agent
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
    }

    import logging
    logging.info("开始下载:")

    response = requests.get(url, headers=headers)

    # 如果没有获取到网页或者获取到网页了,但状态码不对,那么请报异常
    # 4xx , 5xx 都会抛出异常
    # raise关键字 => 抛出异常
    response.raise_for_status()

    # 指定正确的网页编码
    response.encoding = response.apparent_encoding

    # 反爬虫2:增加sleep
    time.sleep(1)
    return response.text

def download_img(url:str) -> bytes:
    """
    这个函数数用来获取url的数据,返回网页的string
    :param url: 应该提供一个网址
    :return: 返回网页的string类型的数据
    """
    # 反爬虫1:添加user-agent
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
    }
    response = requests.get(url, headers=headers)
    # 如果没有获取到网页或者获取到网页了,但状态码不对,那么请报异常
    # 4xx , 5xx 都会抛出异常
    # raise关键字 => 抛出异常
    response.raise_for_status()

    # 指定正确的网页编码
    # response.encoding = response.apparent_encoding

    # 反爬虫2:增加sleep
    time.sleep(1)
    return response.content


# print(download("http://www.baidu3sdf.com"))
# print(download("https://gitee.com/asdfasdf"))

封装的模块:

2.tencent_cos.py

#!/usr/bin/env python
# @FileName :tencent_cos.py.py
# @Time :2024/3/24 11:13
# @Author :huya

# 这是封装的模块

#pip install -U cos-python-sdk-v5

# 复制的代码
# -*- coding=utf-8
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
from qcloud_cos.cos_exception import CosClientError, CosServiceError
import sys
import os
import logging

# 正常情况日志级别使用 INFO,需要定位时可以修改为 DEBUG,此时 SDK 会打印和服务端的通信信息
# logging.basicConfig(level=logging.INFO, stream=sys.stdout)

# 1. 设置用户属性, 包括 secret_id, secret_key, region 等。Appid 已在 CosConfig 中移除,请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成
secret_id = "AKIDIUZRAwb4Jb3TnT7qRq0wlLhpiPt9JI3o"    # 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
secret_key = "mU6eH4qgXbWIzWuMupaCqP3TeaQLAqgN"   # 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
region = 'ap-shanghai'      # 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
                           # COS 支持的所有 region 列表参见 https://cloud.tencent.com/document/product/436/6224
token = None               # 如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入,临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048
scheme = 'https'           # 指定使用 http/https 协议来访问 COS,默认为 https,可不填

config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
client = CosS3Client(config)

bucket='huya-jiayou-1325249148'

# 使用高级接口上传一次,不重试,此时没有使用断点续传的功能
# response = client.upload_file(
#     Bucket='huya-jiayou-1325249148',
#     Key='红楼梦.jpg',
#     LocalFilePath='douban_top250_imgs/1.红楼梦.jpg',
#     EnableMD5=False,
#     progress_callback=None
# )
import logging
def upload(key,local_file):
    # Bucket = 'huya-jiayou-1325249148',
    # Key = key,
    # LocalFilePath = local_file,
    # EnableMD5 = False,
    # progress_callback =
    client.upload_file(
            Bucket=bucket,
            Key=key,
            LocalFilePath=local_file,
            EnableMD5=False,
            progress_callback=None,

        )


    # 获取刚刚上传的图片的地址
    img_url = f"{scheme}://{bucket}.cos.{region}.myqcloud.com/{key}"
    return img_url

日志logging 模块的使用

两种使用方法

#!/usr/bin/env python
# @FileName :8.logging.py
# @Time :2024/3/24 15:02
# @Author :huya

import  logging
import sys

# 创建logger
logger = logging.getLogger("mylogger")

# 设置记忆日志的级别
logger.setLevel(logging.WARNING)

# 创建一个handler , 日志写入的位置
fh = logging.FileHandler("test.log")

# 创建一个日志格式
# 时间  对象  日志级别 消息内容
formater = logging.Formatter("%(asctime)s - %(name)s -%(levelname)s - %(message)s")

# 将日志格式加载到handler 上
fh.setFormatter(formater)
# 将fh 添加到logger 上
logger.addHandler(fh)




logger.debug("debug:hello world")
logger.info("info:hello world")
logger.warning("warning:hello world")
logger.error("error:hello world")
logger.critical("critical:hello world")


# 开发者 ==》详细的输出  ==》Debug

# 用户使用  ==》 INFO

# stream => 输出流 => sys.stdout
# filename => 输出到的文件
# logging.basicConfig(level=logging.INFO, stream=sys.stdout)

# 在bascconfig 里面配置loggin  定制

logging.basicConfig(level=logging.INFO, filename="test2.log", format="%(asctime)s - %(name)s -%(levelname)s - %(message)s")
logging.info("这是一个info信息")
logging.warning("这是一个warning信息")
logging.error("这是一个error信息")
logging.critical("这是一个critical信息")

from mylog import do_sth   # 为什么要导入这个函数?
# 因为可以验证在主函数调用了方法,会不会调用的方法中也用主函数的配置
logging.info("start")
do_sth()
logging.info("end")


调用模块,模块会继承主函数的logging 配置

csv 模块的使用

#coding:utf-8

#!/usr/bin/env python
# @FileName :9.csv.py.py
# @Time :2024/3/24 17:11
# @Author :huya



# csv  ==> 纯文本文件,用逗号分隔数据 ==》表格格式
# open("a.csv","w+")

# 写入数据的时候用逗号分隔,写入的是字符串
# 加上换行符号\n


# 如果我要写的数据放在一个列表中了
import csv
# file = open("a.csv","w+")
# file.read()
# file.close()

# 简写 ==》with 语句块,当退出with 语句块的时候,自动去执行关闭文件的操作
import csv
with open("a.csv","w+") as file:
    file.read()

with open("test.csv","w",newline="") as csv_file:
     #用csv 模块来写该文件
    writer = csv.writer(csv_file)
    writer.writerow(["封面","标题","评分"])
    writer.writerow(["http://a.jpg","西游记","9.8"])
    writer.writerow(["http://a.jpg","红楼梦","9.6"])
    writer.writerow(["http://a.jpg","三国演义","9.4"])
    writer.writerow(data)

我的两个问题

最后的那个csv

还有写日志的,写哪些参数进去作为提示 ok

xpath 爬取top250 未完成 对照视频 3.17最后

课后练习

from tencent_cos import upload
        # 添加保存到cos 的功能(封装成一个函数)
        img_url = upload(key=f"彼岸网4k美女/{count}.{girl_title}.jpg", local_file=girl_cover_path)
        import logging
        logging.info(img_url)
        count += 1

天气数据爬虫

8-15日 http://www.weather.com.cn/weather15d/101250101.shtml

7日 http://www.weather.com.cn/weather/101250101.shtml

数据库mariadb

配置mariadb

1.关闭防火墙 systemctl stop firewalld systemctl disable firewalld

2.安装数据库 yum install -y mariadb-server 由于mysql 将来要收费

3.查看当前启动的端口 3306

				[root@localhost ~]# netstat -tnlp

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1223/master
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1842/mysqld

  1. 开机启动 systemctl enable mariadb

    ​ systemctl start mariadb

5.初始化 mysql_secure_installation

  1. 登录 mysql mysql -uroot -p

  2. use mysql

  3. 给root 用户用123456密码,访问数据库里面的任何表的权限

设置授权
MariaDB [mysql]> grant all privileges on *.* to 'root'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)

MariaDB [mysql]> 

查看

MariaDB [mysql]> select host,user from user;
+-----------------------+------+
| host                  | user |
+-----------------------+------+
| %                     | root |
| 127.0.0.1             | root |
| ::1                   | root |
| localhost             | root |
| localhost.localdomain | root |
+-----------------------+------+
5 rows in set (0.00 sec)



9.create database mytest default character set utf8;

  1. use mytest;

mariadb连接pycharm基础操作

#coding:utf-8
#!/usr/bin/env python
# @FileName :11.pymysql模块.py
# @Time :2024/3/31 11:09
# @Author :huya

# pymysql 用于连接mysql服务器的一个库
# pymysql 连接数据库

# pip install pymysql

import pymysql

# 创建数据库连接
db = pymysql.connect(host="192.168.253.129",
                     port=3306,
                     user="root",
                     password="123456",
                     db="mytest",
                     charset="utf8"
                     )
# 创建游标,使用游标来进行数据库的操作
cursor = db.cursor()
# 创建一个游标之后就会开启一个隐形的数据库事务 事务:需要提交之后才能完成 利于回滚
# 对数据库进行写/更新操作



# 先检查表是否存在,如果存在就删除
sql = "DROP TABLE IF EXISTS app"
cursor.execute(sql)

# 创建一个数据表
sql = """ CREATE TABLE app(
    id INT NOT NULL,
    name CHAR(20))"""

cursor.execute(sql)

# 插入一条数据
sql = "INSERT INTO app(id,name) VALUES(%s,%s)"
cursor.execute(sql,(1,"huya"))
db.commit()  # 提交事务

# 插入一条数据
sql = 'INSERT INTO app(id,name) VALUES(2,"feiruixi")'
cursor.execute(sql)
db.commit()  # 提交事务

# 插入多条数据
sql = 'INSERT INTO app(id,name) VALUES(%s,%s)'
datas = [(3,"zhujunxue"),(4,"高辉")]
cursor.executemany(sql,datas)
db.commit()  # 提交事务

commit 细节

使用多个commit

1.便于回滚 但是写的太多麻烦

2.如果只在最后加commit

当程序出错了,整个都会停止执行,不对数据库进行任何修改 (没执行到commit)

3.能不能把出错前的哪些代码进行正常提交呢?

​ 使用异常处理:在处理异常时 加上commit 语句 注意错误 后面的代码不会执行

try:
	要执行的代码
except Exception as ex:
	#处理异常
	print(ex)
	db.commit()  # 提交
	db.close()

pymysql 模块

#coding:utf-8
#!/usr/bin/env python
# @FileName :11.pymysql模块.py
# @Time :2024/3/31 11:09
# @Author :huya

# pymysql 用于连接mysql服务器的一个库
# pymysql 连接数据库

# pip install pymysql

import pymysql

# 创建数据库连接
db = pymysql.connect(host="192.168.253.129",
                     port=3306,
                     user="root",
                     password="123456",
                     db="mytest",
                     charset="utf8"
                     )
# 创建游标,使用游标来进行数据库的操作
cursor = db.cursor()
# 创建一个游标之后就会开启一个隐形的数据库事务 事务:需要提交之后才能完成 利于回滚
# 对数据库进行写/更新操作



# 先检查表是否存在,如果存在就删除
sql = "DROP TABLE IF EXISTS app"
cursor.execute(sql)

# 创建一个数据表
sql = """ CREATE TABLE app(
    id INT NOT NULL,
    name CHAR(20))"""

cursor.execute(sql)
try:
    # 插入一条数据
    sql = "INSERT INTO app(id,name) VALUES(%s,%s)"
    cursor.execute(sql,(1,"huya"))
    db.commit()  # 提交事务

    # 插入一条数据
    sql = 'INSERT INTO app(id,name) VALUES(2,"feiruixi")'
    cursor.execute(sql)
    db.commit()  # 提交事务

    # 插入多条数据
    sql = 'INSERT INTO app(id,name) VALUES(%s,%s)'
    datas = [(3,"zhujunxue"),(4,"高辉")]
    cursor.executemany(sql,datas)
    db.commit()  # 提交事务

    # 查询
    sql = "SELECT id,name FROM app"
    cursor.execute(sql)
    result1 = cursor.fetchone()
    print("result1:",result1)
    result2 = cursor.fetchmany(2)
    print("result2:",result2)

    result3 = cursor.fetchall()
    print("result3:",result3)

    # 更新数据
    sql = "UPDATE app SET name='费瑞曦'WHERE name='feiruixi'"
    cursor.execute(sql)

    sql = "SELECT id,name FROM app"
    cursor.execute(sql)
    result3 = cursor.fetchall()
    print("result3:",result3)

    # 更新数据
    sql = "UPDATE app SET name='%s'WHERE id=%s"
    sql = sql % ("费瑞曦",1)

    1/0

    # 更新数据
    name = "费瑞曦"
    id = 3
    sql = f"UPDATE app SET name='{name}' WHERE id={id}"
    cursor.execute(sql) # 执行更新语句
    sql = "SELECT id,name FROM app"
    cursor.execute(sql) # 执行查询语句
    result3 = cursor.fetchall()  # 将查询语句的所有  赋值给 result3
    db.commit() # 提交
    print("result3:",result3)

    # 删除
    sql = "DELETE FROM app WHERE id=4"
    # sql = "DELETE FROM app WHERE id=(1,2)"
    cursor.execute(sql)
    sql = "SELECT id,name FROM app"
    cursor.execute(sql)
    result3 = cursor.fetchall()
    print("result3:",result3)
    db.commit() # 提交
    db.close()
except ZeroDivisionError as ex:
    print(ex)
    print("这是一个非0的错误")
except Exception as ex:
    #处理异常
    print(ex)
    db.commit()  # 提交
    db.close()




# 异常处理
# try...except
"""
except 可以又多个分支
捕获异常的时候,要将子类写在前面
except 匹配过程从前到后

try:
    可能出错的代码段
except NameError as ex:
    pass
except TypeError as ex:
    pass

# 捕获所有异常类型   
except Exception as ex:
    处理代码

"""

sqlalchemy模块

#coding:utf8
#!/usr/bin/env python
# @FileName :12.sqlalchemy.py
# @Time :2024/3/31 15:53
# @Author :huya

# sqlalchemy基于pymysql 工具包,支持对象关系映射(ORM)
# pip install sqlalchemy
# pip install pymysql

from sqlalchemy import create_engine,text

# pymysql.connect(参数....)
USER = "root"
PASSWD = "123456"
HOST = "192.168.253.129"
POST = "3306"
DBNAME = "mytest"
DB_URL = f"mysql+pymysql://{USER}:{PASSWD}@{HOST}:{POST}/{DBNAME}?charset=utf8"

# 创建数据库引擎
engine = create_engine(DB_URL)
# 创建连接
con = engine.connect()

# con => pymysql 游标 cur

# 创建数据表
sql = text("DROP TABLE IF EXISTS app2")
con.execute(sql)

sql = """create table app2 (
        id int not null,
        name char(20)
        )"""
con.execute(text(sql))

# 插入一条数据
sql = text("INSERT INTO app2(id,name) VALUES(1,'huya')")
con.execute(sql)

sql = text("INSERT INTO app2(id,name) VALUES(1,'huya'),(2,'zhujunxue'),(3,'gaohui'),(4,'feiruixi')")
con.execute(sql)

# 插入一条数据
sql = "INSERT INTO app2(id,name) VALUES(:id,:name)"
con.execute(text(sql),{"id":5,"name":"李昊阳"})
con.commit()

# # 插入多条数据
# sql = 'INSERT INTO app2(id,name) VALUES(%s,%s)'
# datas = [{"id":3, "name":"zhujunxue"}, {"id":4,"name": "高辉"}]
# con.execute(text(sql),datas)
# con.commit()  # 提交事务




# 查询数据
sql = "select * from app2"
result = con.execute(text(sql))
print("result1",result.fetchone())
print("result1",result.fetchmany(2))
print("result1",result.fetchall())

# 更新数据
sql = "update app2 set name='胡亚' WHERE name='huya'"
con.execute(text(sql))
con.commit()

#更新数据
# sql = "UPDATE app2 SET name='%s'WHERE id=%s"
# sql = sql % ("费瑞曦",1)
# con.commit()
# con.close()

#更新数据
# name = "费瑞曦"
# id = 3
# sql = f"UPDATE app2 SET name='{name}' WHERE id={id}"
# con.commit()
# con.close()

# 删除数据
sql = "DELETE FROM app2 WHERE id=4"
con.execute(text(sql))
con.commit() # 提交
con.close()

将豆瓣读书top250 写入数据库中

sql = “UPDATE app SET name='%s’WHERE id=%s”
sql = sql % (“费瑞曦”,1)

1/0

# 更新数据
name = "费瑞曦"
id = 3
sql = f"UPDATE app SET name='{name}' WHERE id={id}"
cursor.execute(sql) # 执行更新语句
sql = "SELECT id,name FROM app"
cursor.execute(sql) # 执行查询语句
result3 = cursor.fetchall()  # 将查询语句的所有  赋值给 result3
db.commit() # 提交
print("result3:",result3)

# 删除
sql = "DELETE FROM app WHERE id=4"
# sql = "DELETE FROM app WHERE id=(1,2)"
cursor.execute(sql)
sql = "SELECT id,name FROM app"
cursor.execute(sql)
result3 = cursor.fetchall()
print("result3:",result3)
db.commit() # 提交
db.close()

except ZeroDivisionError as ex:
print(ex)
print(“这是一个非0的错误”)
except Exception as ex:
#处理异常
print(ex)
db.commit() # 提交
db.close()

异常处理

try…except

“”"
except 可以又多个分支
捕获异常的时候,要将子类写在前面
except 匹配过程从前到后

try:
可能出错的代码段
except NameError as ex:
pass
except TypeError as ex:
pass

捕获所有异常类型

except Exception as ex:
处理代码

“”"


## sqlalchemy模块

#coding:utf8
#!/usr/bin/env python
#@FileName :12.sqlalchemy.py
@Time :2024/3/31 15:53
#@Author :huya

#sqlalchemy基于pymysql 工具包,支持对象关系映射(ORM)
pip install sqlalchemy
pip install pymysql

from sqlalchemy import create_engine,text

#pymysql.connect(参数…)
USER = “root”
PASSWD = “123456”
HOST = “192.168.253.129”
POST = “3306”
DBNAME = “mytest”
DB_URL = f"mysql+pymysql://{USER}:{PASSWD}@{HOST}:{POST}/{DBNAME}?charset=utf8"

创建数据库引擎

engine = create_engine(DB_URL)

创建连接

con = engine.connect()

#con => pymysql 游标 cur

创建数据表

sql = text(“DROP TABLE IF EXISTS app2”)
con.execute(sql)

sql = “”“create table app2 (
id int not null,
name char(20)
)”“”
con.execute(text(sql))

插入一条数据

sql = text(“INSERT INTO app2(id,name) VALUES(1,‘huya’)”)
con.execute(sql)

sql = text(“INSERT INTO app2(id,name) VALUES(1,‘huya’),(2,‘zhujunxue’),(3,‘gaohui’),(4,‘feiruixi’)”)
con.execute(sql)

插入一条数据

sql = “INSERT INTO app2(id,name) VALUES(:id,:name)”
con.execute(text(sql),{“id”:5,“name”:“李昊阳”})
con.commit()

插入多条数据

#sql = ‘INSERT INTO app2(id,name) VALUES(%s,%s)’
datas = [{“id”:3, “name”:“zhujunxue”}, {“id”:4,“name”: “高辉”}]
con.execute(text(sql),datas)
con.commit() # 提交事务

查询数据

sql = “select * from app2”
result = con.execute(text(sql))
print(“result1”,result.fetchone())
print(“result1”,result.fetchmany(2))
print(“result1”,result.fetchall())

更新数据

sql = “update app2 set name=‘胡亚’ WHERE name=‘huya’”
con.execute(text(sql))
con.commit()

#更新数据
#sql = “UPDATE app2 SET name='%s’WHERE id=%s”
#sql = sql % (“费瑞曦”,1)
#con.commit()
con.close()

#更新数据
name = “费瑞曦”
id = 3
sql = f"UPDATE app2 SET name=‘{name}’ WHERE id={id}"
con.commit()
con.close()

删除数据

sql = “DELETE FROM app2 WHERE id=4”
con.execute(text(sql))
con.commit() # 提交
con.close()


## 将豆瓣读书top250 写入数据库中
















版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_70577826/article/details/137213062

智能推荐

使用 arm-linux-androideabi-addr2line 工具定位 libunity.so 崩溃问题-程序员宅基地

文章浏览阅读710次,点赞13次,收藏7次。它的名称有点不同 - aarch64-linux-android-addr2line。尽管该实用程序的名称不包含单词arm,但它成功地解密了arm64-v8下的堆栈跟踪,并通常感知arm64-v8的字符。是 NDK 自带的调试工具,可以用来分析 so 崩溃时输出的的内存地址。之后就是通过 cmd 进入到这个路径。找到了 64 位所需的实用程序。_arm-linux-androideabi

javaweb-邮件发送_javaweb发送邮件-程序员宅基地

javaweb-邮件发送 摘要: 本文介绍了邮件传输协议(SMTP和POP3)以及电子邮件的发送和接收过程。还讨论了纯文本文件、带图片和附件的邮件发送方法,以及通过servlet方式注册邮箱和使用springboot框架发送邮件的实现。

element-ui table 设置表格滚动条位置_element table 滚动条位置-程序员宅基地

文章浏览阅读4.3k次,点赞6次,收藏11次。在切换不同页面时(被 keep-alive 缓存的组件间切换),页面中的element-ui table的滚动条位置没有停留在原来的位置。目前需要切换不同的页面返回来后,滚动条保持在原来的位置。_element table 滚动条位置

前端开发经验总结_属性值[session.getattribute("strpath")]引用["],在值内使用时必须-程序员宅基地

文章浏览阅读2.6k次。 我设置nowrap和不设置nowrap效果都一样。就是表格随着文字自动伸展,为什么? →回答问题:TD元素noWrap属性的行为与TD元素的width属性有关。 ◆如果未设置TD宽度,则noWrap属性是起作用的。◆如果设置了TD宽度,则noWrap属性是不起作用的。 http://www.blueidea.com/tech/web/2003/943.as_属性值[session.getattribute("strpath")]引用["],在值内使用时必须被转义。

JS如何把Object对象的数据输出到控制台中_前端怎么通过控制台查看字段取值-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏3次。 前端时间在编写程序时遇到这样一个问题,即在前端页面通过一些js框架自带的异步请求返回的数据类型为Object数据类型,笔者根据网上查阅到的资料,找到以下这种简单的方式://把Object类型转为Json数据格式,再通过console命令在控制台中打印出来console.log("xhr的值为:"+JSON.st..._前端怎么通过控制台查看字段取值

8.cc.Button组件使用详解_cc button.start-程序员宅基地

文章浏览阅读556次。1. cc.Button添加按钮的方法 2种方式 (1)直接创建带Button组件的节点; (2) 先创建节点,再添加组件;按钮组件, 按钮是游戏中最常用的组件, 点击然后响应事件;按钮的过渡效果: 过渡: 普通状态, 鼠标滑动到物体上, 按下状态, 禁用状态 (1)没有过渡,只有响应事件; (2)颜色过渡, 过渡效果中使用颜色; (3)精灵..._cc button.start

随便推点

计算机专业游戏本推荐,2018高性价比游戏本推荐_游戏笔记本哪个好-太平洋电脑网...-程序员宅基地

文章浏览阅读245次。【PConline海选导购】晃眼间,秋风又起,让人振奋的开学季又要到来了!虽然说没有学习压力的暑假,在家着实悠哉,但想到回校后可以跟小伙伴们一起各种开黑吃鸡,是不是就感到很兴奋呢?说到“吃鸡”这种吃配置的游戏,就不得不说游戏本了,毕竟普通的笔记本电脑很难给我们带来畅快的游戏体验。而近年来游戏本市场俨然成为了各大厂商的必争之地,而随着开学季的到来,各大厂商更是推出了众多促销活动,下面就让我们一起来看..._计应专业游戏本

codePen按钮样式学习

看到codepen里面有的按钮搞得很炫酷,但其实也不是很难,就学习记录一下。

服务器维护中没法直播游戏,我的世界盒子显示维护中如何进入战堂服务器-程序员宅基地

文章浏览阅读408次。时间:2021-08-11编辑:hxh斗罗大陆魂师对决火雨队怎么搭配?火雨队是近期非常热门的一套阵容,不少玩家想了解该阵容,那么下面就让小编给大家带来斗罗大陆魂师对决火雨队阵容推荐,感兴趣的小伙伴们一起来看看吧。时间:2021-08-11编辑:hxh玩家在巅峰演武副本中不知道怎么打秦明,秦明的盾很厚不知道怎么破?那么下面就让小编给大家带来斗罗大陆魂师对决巅峰演武秦明破盾攻略,感兴趣的小伙伴们一起来...

GNU Radio之Schmidl & Cox OFDM synch.底层C++实现

在 GNU Radio OFDM 系统中,一个非常重要的环节是在接收端准确地同步和检测发送端发出的信号。这就是 Schmidl & Cox 同步算法发挥作用的地方。Schmidl & Cox 算法是一种用于 OFDM 信号的时间同步的技术。本文对其底层 C++ 源码进行学习记录。

项目开发规范

REST,表述性状态转换,他是一种软件架构风格使用URL定位资源,HTTP动词描述操作根据发出请求类型来区分操作此为风格,是约定方式,可以打破描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。

3.8设计模式——State 状态模式(行为型)

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。