实训小结:Python入门到爬虫

  • Python实训
    • 一、基础入门
      • 1. 行业
      • 2. 搭建开发环境
      • 3.如何使用PyCharm创建一个Python项目
      • 4. 如何在Pycharm创建的Python项目中,创建Python文件
      • 5. 代码
    • 二、字符串
      • 1. 字符串
      • 2. 数据存储
    • 三、面向对象
      • 1.概念
      • 2.代码
      • 3.方法(函数)
    • 四、文件I/O、邮件、GUI
      • 1,文件操作
      • 2,time
      • 3,邮件发送
      • 4,可视化
    • 五、前端网页
        • 为什么学?
        • 代码学习路径
      • 1.Html
      • 2.CSS(层叠样式表):
    • 六、Python爬虫
      • 1.静态爬取
      • 2.资源下载(图片、文件、视频)
      • 3.动态资源获取
      • 4. 爬取数据存入数据库
    • 七、Flask
      • 小技巧:创建项目,环境与代码应分开放置
      • 1.安装flask和pymysql
      • 2. Flask入门

Python实训

一、基础入门

1. 行业

2. 搭建开发环境

​ 1,安装Python3.6版本
​ 一定要勾选将python所在环境添加到path
​ 2,安装开发工具PyCharm

3.如何使用PyCharm创建一个Python项目

 1,选择create new project2,修改项目存储路径,路径的最后一个为项目名称

4. 如何在Pycharm创建的Python项目中,创建Python文件

​ 1,选中项目
​ 2,点击鼠标右键,选择new
​ 3,选择python file

5. 代码

 1,注释单行注释:#xxxx多行注释:'''xxxx'''2,输出与输入输出:print("要输出内容")输入:输入的内容 = input("提示字")3,变量Python中之间写变量名就好变量名要求:小驼峰见名知意不能使用数字,特殊符号开头4,数据类型可以通过type获取变量的数据类型如:num = 10type(num)5,数据类型转换str()int()float()chr()6,运算算数运算+,-,*,/,%逻辑运算<,>,<=,>=,==,!=and or not赋值运算=,+=,-=,*=,/=,%=7,分支语句Python中分支语句为if语法格式如下:
         if(条件表达式1):当条件表达式1为真时,执行此处代码elif(条件表达式2):当条件表达式2为真时,执行此处代码elif(条件表达式3)当条件表达式3为真时,执行此处代码...else:当以上条件都为假时,执行此次代码

​ 8,循环语句
​ Python中循环语句:while
​ 语法格式参考Java
​ 9,遍历
​ Python中的遍历for
​ 类似语句Java的增强for循环
​ 10,随机数
​ 1,导包
​ 2,获取随机数

二、字符串

1. 字符串

str

2. 数据存储

  • 临时存储:随着程序的关闭而消失

    变量

    类对象

    列表等

    java中临时存储

    ​ 数组

    ​ 对象

    ​ list

    ​ set

    ​ map

    python中临时存储

    ​ 变量

    ​ 对象

    ​ 元组:类似于java中的数组,使用小括号定义,数据不可变

    ​ 列表:类似于java中ArraryList,使用中括号定义,内容可变

    ​ 字典:类似于java中map,使用大括号定义,键值对应。

  • 持久化存储:不会随着程序而消失

    ​ 文件
    ​ 数据库
    ​ 网络存储

三、面向对象

1.概念

面向对象是一种思维

与其对立的是面向过程将大象装进冰箱里需要几步

  开门    装    关门

面向对象思维考虑

  1.事物中存在哪些对象

​ 2.考虑对象与对象的关系

对象:一种真实的事物

类:将一类具有相同属性行为的形成的概念

真实生活:先有对象后有类

代码中:需要类才可创建对象

子类->父类 ,没有风险

父类->子类 存在类型转换异常继承多态封装

2.代码

__init__ 相当于java的构造方法__变量名 # 定义私有属性,私有属性在类外部无法直接进行访问
self  #类似于java的构造函数,self类似于java的this
class C(A,B)
#多继承# 需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,
# python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。

3.方法(函数)

  • java方法

    ​ 访问权限修饰符[修饰符] 返回类型 方法名([形参列表]){ 方法体 return; }

  • java方法使用

    ​ 方法名([实参列表])

  • python方法

    ​ def 方法名([形参列表]):

    ​ 方法体

    ​ return;

  • python方法的使用

    ​ 方法名([实参列表])

  • python中实参可以按照形参的顺序进行传输

  • python有默认赋值的形参可以不进行传值

  • 有返回值类型的方法可以使用变量进行接收

  • 可以有多个返回值接收

  • 好处

    方法作用:

    ​ 1.封装代码

    方法的好处: 1.保护内部代码 2.方便外部调用 3.降低代码耦合度

四、文件I/O、邮件、GUI

1,文件操作

os:导包

​ 判断文件是否存在

​ os.path.exists(文件路径)

​ 当返回值为true时,表示文件存在,反之不存在

​ 如何创建多级文件夹

​ os.makedirs(“文件夹路径”)

​ 每个单词之间的/表示为下级文件夹

​ 如:a/b/c,创建a文件夹,在a文件夹下,创建b文件夹,在b文件下,创建c文件夹

open:打开文件

​ 文件对象 = open(文件路径,模式,编码格式)

         文件路径:相对路径相对于当前py文件所在的位置../:上一层./:当前路径下/xx:下一层绝对路径文件在电脑中的位置:如c://a/b/test.txt

​ 如:文件对象 = open(“文件所在路径”,mode=“模式”,encoding=“utf-8”)

​ 模式:

​ w:写,如果文件不存在,可以帮助我们创建文件,如果文件已经存在,删除后再创建文件

​ r:读

​ a:追加,如果文件不存在,可以帮助我们创建文件,如果文件已经存在,使用当前文件

​ 文件操作

​ 读:文件对象.write(写入的内容)

​ 文件对象.write(写入的内容)

​ 写:文件对象.read()读取文件中所有内容

​ 读取到的内容 = 文件对象.read()

​ 关闭:文件对象.close()

​ 文件对象.close()

2,time

​ time.sleep(阻塞时间单位秒)

​ 获取当前时间time.time()

3,邮件发送

​ 需要的包

​ from email.mime.text import MIMEText

​ import smptlib

​ 步骤

​ 1,准备需要的数据

​ 发送者昵称

​ 发送者账号

​ 发送者账号授权码

​ 接受者邮箱

​ 邮件标题

​ 邮件正文

​ 2,组装邮件:MIMEText

    使用发送人昵称标题正文from email.mime.text import MIMETextmsg = MIMEText(正文)msg["From"] = 发送人昵称msg["subject"] = 标题

​ 3,登录邮箱smtplib

     1,获取客户端import smtplibclient = smtplib.SMTP("smtp.qq.com",25)2,登录发送人邮箱发送人授权码client.login(发送人邮箱,发送人授权码)

​ 4,发送邮件

​ 发送人邮箱

​ 收件人邮箱

​ 邮件

client.sendmail(发送人邮箱,收件人邮箱,msg=msg.as_string())

​ 5,退出登录

​ client.quit()

4,可视化

​ 类似于Java中的GUI

​ 所需包:

​ tkinter

​ 窗口

​ 创建窗口

​ window=tkinter.Tk()

​ 设置窗口

​ 设置窗口标题

​ 设置窗口大小

​ 设置窗口宽高是否可变

​ 显示窗口

​ mainloop()

​ 组件

​ 文本:Lable

​ 属性:text:展示的文本

​ 输入框:Entry

​ 属性:width:宽度

​ 按钮:Button

​ 属性:command:点击后执行的方法,text:展示的文本 注意:所有组件添加完成后,都需要显示 pack

五、前端网页

为什么学?

​ 因为爬虫需要从网页中获取数据,所以需要了解网页

​ 如果后期制作flask项目,需要前端展示,也需要会前端网页

代码学习路径
  1. 搭建环境

  2. 安装开发工具

  3. 创建项目

    ​ 项目结构
    ​ css:存放css代码文件
    ​ img:存放项目中使用的图片文件,注意网页支持gif图
    ​ js:存放js代码文件
    ​ index.html:项目自带的网页文件
    ​ 注意:一个项目中,可以有多个网页文件

  4. 编写代码

1.Html

标签格式
<标签名 ></标签名>

         如:<span></span><p></p><h1></h1><ul></ul><li></li><a></a>....

​ 可以容纳别的标签
​ <开始标签 属性区>内容区</结束标签>

​ <标签名 />

​ 如:

             <img /><meta /><br /><hr />

​ 称为最终标签,不能给其中嵌套别的标签
​ <标签名 属性区 />

所有标签都有id与class属性**id:类似于人的身份证号,一个网页中id的值不允许重复****class:类似于对标签进行分类,值可以重复****所有标签都可以设置点击事件**

标签:
文本
span:文本标签,新的
font:文本标签,旧的
h1~h6:标题标签
p:段落
a:超链接
属性:href
作用:
跳转外部网址
跳转内部网址
跳转当前网页中指定区域

​ 图片
img:图片展示标签
属性:src(值为图片所在地址)
注意:支持gif图
输入

​ input:输入
​ 属性:
​ type
​ 值(系统提供的,不能自定义)
​ text:文本输入(默认)
​ password:密码输入
​ button:按钮
​ radio:单选
​ checkbox:多选
​ value
​ 值(自定义)
​ 当type类型为text或password时,该属性值为输入框中的输入内容
​ 当type类型为button时,该属性值为按钮上展示的内容
​ 当type类型为radio或checkbox时,表示该按钮对应的值
​ name:
​ 值(自定义)
​ 当type类型为radio或checkbox时,name属性值相同则为一组
​ 媒体
​ audio:音频
​ src:资源文件所在位置
​ video:视频
​ 其他
​ br:换行
​ hr:水平分割线
​ ul:无序列表
​ li:列表子项
​ ol:有序列表
​ li:列表子项
​ select:选择器
​ option:子项
​ div:块

2.CSS(层叠样式表):

     作用:美化,移动html标签1,在哪里书写css代码方案1:(不建议使用)在标签的style属性中书写(内联样式)方案2:(新手使用)在head标签中书写style标签,在style标签书写css代码方案3:(熟练后使用)在css文件中书写,通过link标签引入到需要的html文件中2,如何在css中寻找html标签?通过选择器进行寻找常用的选择器有?id选择器 #名class选择器 .名标签选择器 p,a,div...统配选择器 *{}3,如果多个选择器,对同一个标签设置样式,听谁的(选择器权重)选择器优先级相同时:谁后写,听谁的选择器优先级不同时:听选择器优先级高的选择器优先级统配选择器 < 标签选择器 < class选择器 < id选择器 < 内联样式4,可以美化什么?*文字文字大小 font-size字体    font-family字体样式 font-style笔画粗细 font-weight颜色 color/*** 颜色*         系统定义的颜色*        六位调色法*          #红绿蓝*       rgb*        rgba* 光的三原色*        红绿蓝* 每个颜色的取值:0~255 十六进制00~FF*//*color: #009900;*//*color: rgb(0,0,255);*//*** a为透明度* 1,不透明* 0,全透明*/rgba(0,0,0,0.5);行高 line-height下划线 text-decoration:underline*背景背景颜色  background-color背景图片  background-image:url("") ;背景大小  background-size/*** 背景大小* 1参:背景宽度    可以使用px,也可以%* 2参:背景高度    可以使用px,也可以%*/背景是否平铺 background-repeat/*** 背景是否平铺*       no-repeat:不平铺*      repeat:平铺(默认)*/背景位置 background-position/*** 背景位置* 1参:左右*        左:left*         右:right*        中:center* 2参:上下*        上:top*      下:bottom*       中:center*/*大小宽高  width height内边距 padding 上右下左外边距 margin 上右下左边框 border,border-radius,border-top-left-radius盒子模型分类 div ie盒子:box-sizing:border-box  *计算/*** 标准盒子组件占地* 组件占地宽/高 = 宽/高+左右/上下内边距 +左右/上下边框 + 左右/上下外边距 * IE盒子组件占地:ie盒子计算中不减外边距* 组件占地宽/高 = 宽/高+左右/上下外边距 */*位置定位 position相对定位  relative相对定位元素的定位是相对其正常位置。绝对定位  absolute绝对定位的元素的位置相对于最近的已定             位父元素,如果元素没有已定位的父元                      素,那么它的位置相对于<html>:浏览器窗口定位 fixed元素的位置相对于浏览器窗口是固定位置居中margin:上下的外边距  左右的外边距auto:自适应注意:组件必须是块元素好处:不会影响别的标签位置定位居中left:%50margin-left:-(width/2)px;浮动层级: z-index左浮动 float:left右浮动 float:right清理浮动导致的空间塌陷 clear*阴影box-shadow:x  y  阴影宽度 阴影颜色*动画*过渡5,标签分为三类:*行内元素设置宽高无效,内容多宽,组件多宽:span,a*行内块元素设置宽高有效,不独占一行:input,img等*块元素设置宽高有效,独占一行:p,div,li,h1~h6d等*如何修改标签元素类型display属性hidden可以隐藏某个元素,占位none 隐藏元素,不占位block:块元素inline-block:行内块元素inline:行内元素

六、Python爬虫

1.静态爬取

  1. #网络请求的包:from urllib.request import Request, urlopen
    #解压或压缩数据:import gzip
    #https网址协议验签:import ssl

    #将数据转换为html格式:from lxml import etree

from urllib.request import Request, urlopen#网络请求的包
import gzip#解压或压缩数据
import ssl#https网址协议验签
from lxml import etree
if __name__ == '__main__':# https协议验签ssl._create_default_https_context = ssl._create_unverified_context;path="https://www.biqooge.com/0_3/5372509.html";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 Edg/91.0.864.67","accept-encoding":"gzip"};#封装请求req=Request(url=path,headers=headers);#打开连接conn = urlopen(req);#判断连接是否成功,响应码是否为200if conn.code == 200:#获取后台数据data = conn.read();#判断是否为压缩格式isGzip=conn.headers.get("content-encoding");print(isGzip);if isGzip=="gzip":#解压数据data=gzip.decompress(data);#改变数据的编码格式data=data.decode(encoding="gbk");#解析数据#解析1. 将数据转换为html格式html=etree.HTML(data);#获取章节名称,,准备xpathtitleXpath="//div[@class='bookname']/h1/text()";titleTag=html.xpath(titleXpath);print(html)if len(titleTag)>0:print(titleTag[0])textXpath="//div[@id='content']/text()";textTag=html.xpath(textXpath);text="".join(textTag);text=text.split();text="\n".join(text);print(text);#存入本地file=open(file="%s.txt"%(titleTag[0]),mode="a",encoding="utf-8");file.write(titleTag[0]+"\n");file.write(text);file.close();passelse:print("连接失败");
  1. 爬取目录,然后进入具体列表项爬
from urllib.request import Request, urlopen#网络请求的包
import gzip#解压或压缩数据
from lxml import etree
import demo01_爬虫 as pc
import time
import randompaths={}def dowmload():path = "https://www.biqooge.com/0_3/";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 Edg/91.0.864.67","accept-encoding": "gzip"};# 封装请求req = Request(url=path, headers=headers);# 打开连接conn = urlopen(req);# 判断连接是否成功if conn.code == 200:# 获取后台数据data = conn.read();# 判断是否为压缩数据格式isGzip = conn.headers.get("content-encoding");print(isGzip);if isGzip == "gzip":# 压缩数据data = gzip.decompress(data);# 改变数据的编码格式data = data.decode(encoding="gbk");# 解析数据# 解析1. 将数据转换为html格式html = etree.HTML(data);# 获取a标签的位置aXpath = "//div[@id='list']/dl/dd/a";aTag = html.xpath(aXpath);print(aTag);n = 5;for a in aTag:if n <= 0:break;itemPath = a.xpath("./@href");itemName = a.xpath("./text()");tt = random.randint(1, 4);time.sleep(tt);if len(itemPath) > 0 and len(itemName) > 0:print(itemName[0], "https://www.biqooge.com" + itemPath[0]);paths[itemName[0]]="https://www.biqooge.com" + itemPath[0];n-=1;passelse:print("连接失败");
if __name__ == '__main__':dowmload();keys=paths.keys();for path in keys:pc.main(paths[path]);

2.资源下载(图片、文件、视频)

  1. 图片获取
'''
网络请求的包请求:Request打开网址:urlopen下载文件:urlretrieve    urlretrieve(url="图片路径",filename="文件存储路径")
'''
from urllib.request import Request,urlopen,urlretrieve #urlretrieve(url="图片路径",filename="文件存储路径")
#用于解压数据  etree.Html(data)
from lxml import etree
#解压或者压缩数据 gzip.decompress()
import gzip
#https的网址进行验签使用
import ssl
#文件操作
import os
if __name__ == '__main__':#验签ssl._create_default_https_context = ssl._create_unverified_context;#请求地址path="https://www.baidu.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 Edg/91.0.864.67","accept-encoding":"gzip"}#封装请求req = Request(url=path,headers=headers);# 打开连接conn = urlopen(req);#判断是否成功if conn.code==200:#读取服务器返回数据data= conn.read();#因为下载是压缩格式,需要解压data = gzip.decompress(data);#因为中文乱码,所以需要将编码格式改为网站的编码data = data.decode(encoding="utf-8");#解析#转为html格式html = etree.HTML(data);#准备要获取的数据的xpathimgTag= "//img[@id='s_lg_img']/@src";#开始解析获取数据imgs = html.xpath(imgTag);#获取地址并完善if len(imgs)>0:imgPath = "https:"+imgs[0];print(imgs);#判断文件夹是否存在if not os.path.exists("./img"):#不存在就创建os.makedirs("./img");#下载urlretrieve(url=imgPath,filename="./img/bd.png");passelse:print("连接失败!");

3.动态资源获取

  1. 动态百度图爬取

    #谷歌浏览器包
    from selenium.webdriver import Chrome
    from urllib.request import urlretrieve
    # import time
    #百度图
    import os
    if __name__ == '__main__':#加载驱动#chrom = Chrom("驱动地址")chrom = Chrome("./chromedriver.exe");#发起请求chrom.get(url="https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=index&fr=&hs=0&xthttps=111110&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E9%A3%8E%E6%99%AF&oq=%E9%A3%8E%E6%99%AF&rsp=-1");#阻塞程序一段时间,让浏览器加载动态数据# time.sleep(10);#获取class属性值为xxx# find_elements_by_class_name:通过class的属性值获取对应的标签# find_element_by_id:通过标签的id获取标签# find_elements_by_tag_name:通过标签名获取标签imgs=chrom.find_elements_by_class_name("main_img");#遍历数据num=0;for img in imgs:# get_attribute:获取指定属性的属性值# 获取到的标签.text:获取标签属性区的内容#获取img里面的srcimgPath=img.get_attribute("src");print(imgPath);#保存本地if not os.path.exists("./img"):os.makedirs("./img");num+=1;#下载到本地urlretrieve(url=imgPath,filename="./img/%d.jpg"%(num));print(imgs);#退出浏览器chrom.quit();
    

4. 爬取数据存入数据库

  1. 存入数据库

    from urllib.request import Request,urlopen
    import ssl
    import gzip
    from lxml import etree
    #python操作mysql所用的包
    #import pymysql
    def getData(path,headers,encoding):ssl._create_default_https_context = ssl._create_unverified_contextreq = Request(url=path,headers=headers)conn = urlopen(req)if conn.code == 200:data = conn.read()if conn.headers.get("Content-Encoding") == "gzip":data = gzip.decompress(data)data = data.decode(encoding=encoding)return datapasselse:print("错误码:",conn.code)return ""pass
    '''
    数据库操作导包 pymysql
    '''
    #python操作mysql所用的包
    import pymysql
    def saveBook(bookName,bookPath):#获取数据库连接对象'''host:连接的数据库所在的地址ipport:端口号user:账号password:密码database=数据库名charset=编码格式'''conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="mysql",database="test",charset="utf8");#获取游标,执行sqlcursor = conn.cursor();sql = "insert into books (b_name,b_path) values('%s','%s')"%(bookName,bookPath);#执行sql'''如果sql为查询语句,返回为查询结果集;如果为增删改,返回为受影响行数'''result=cursor.execute(sql);if result<1:print("插入失败!");else:#如果对数据库进行了更改就需要进行提交conn.commit();#关闭数据库cursor.close()conn.close()if __name__ == '__main__':path="https://www.xbiquge.la/xiaoshuodaquan/";headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36","Accept-Encoding":"gzip"};booksData=getData(path=path,headers=headers,encoding="utf-8");bookshtml = etree.HTML(booksData);booksXpath="//div[@id='main']/div[@class='novellist']/ul/li/a";books_a = bookshtml.xpath(booksXpath);for book_a in books_a:bookName = book_a.xpath("./text()");bookPath = book_a.xpath("./@href");# print("%s--%s"%(bookName[0],bookPath[0]));saveBook(bookName[0],bookPath[0]);print(booksData);
  2. 读取数据库

    #python操作mysql所用的包
    #import pymysqlclass Book:def __init__(self,id,name,path):self.id=id;self.name=name;self.path=path;def __str__(self):return ("id:%d  name:%s  path:%s"%(self,id,self.name,self.path));
    '''
    数据库操作导包 pymysql
    '''
    #python操作mysql所用的包
    import pymysql
    def getBooks():list=[];# 获取数据库连接对象conn = pymysql.connect(host="127.0.0.1", port=3306, user="root",password="mysql", database="test", charset="utf8");# 获取游标,执行sqlcursor = conn.cursor();sql = "select * from books";# 执行sql'''如果sql为查询语句,返回为查询结果集;如果为增删改,返回为受影响行数'''result = cursor.execute(sql);#fetchall获得查询结果元组result = cursor.fetchall();for book in result:id = book[0];name = book[1];path = book[2];b=Book(id=id,name=name,path=path);list.append(b);print("查询完成!");return list;if __name__ == '__main__':# 查询mysql数据库中books表中数据books = getBooks();num=0;for book in books:if num>10:break;print(book.name+":\t"+book.path);num+=1;
    
  3. 读取数据库内容并进一步处理,再次请求存入

    from urllib.request import Request,urlopen
    import ssl
    import gzip
    from lxml import etree
    #python操作mysql所用的包
    #import pymysqlclass Book:def __init__(self,id,name,path):self.id=id;self.name=name;self.path=path;def __str__(self):return ("id:%d  name:%s  path:%s"%(self,id,self.name,self.path));
    class Item:def __init__(self,id,bid,name,path):self.id=id;self.bid=bid;self.name=name;self.path=path;def __str__(self):return ("第%d章:%s---%s"%(self.id,self.name,self.path));
    import pymysql
    def saveItem(bid,name,path):#获取数据库连接对象'''host:连接的数据库所在的地址ipport:端口号user:账号password:密码database=数据库名charset=编码格式'''conn = pymysql.connect(host="127.0.0.1",port=3306,user="root",password="mysql",database="test",charset="utf8");#获取游标,执行sqlcursor = conn.cursor();sql = "insert into items (b_id,i_name,i_path) values(%d,'%s','%s')"%(bid,name,path);#执行sql'''如果sql为查询语句,返回为查询结果集;如果为增删改,返回为受影响行数'''result=cursor.execute(sql);if result<1:print("插入失败!");else:#如果对数据库进行了更改就需要进行提交conn.commit();#关闭数据库cursor.close()conn.close()
    #获取一本书的所有章节信息存入
    def getData(headers,book):ssl._create_default_https_context = ssl._create_unverified_contextreq = Request(url=book.path,headers=headers)conn = urlopen(req)if conn.code == 200:data = conn.read()if conn.headers.get("Content-Encoding") == "gzip":data = gzip.decompress(data)itemsData = data.decode(encoding="utf-8");itemshtml = etree.HTML(itemsData);item_aXpath = "//div[@id='list']/dl/dd/a";item_apath= itemshtml.xpath(item_aXpath);for item_a in item_apath:i_name=item_a.xpath("./text()");i_path = item_a.xpath("./@href");i_path=book.path+i_path[0];bid = book.id;# print("%s--%s"%(bookName[0],bookPath[0]));saveItem(bid,i_name[0],i_path);print("完成!");passelse:print("错误码:",conn.code)return ""pass
    '''
    数据库操作导包 pymysql
    '''
    #python操作mysql所用的包
    import pymysql
    def getBooks():list=[];# 获取数据库连接对象conn = pymysql.connect(host="127.0.0.1", port=3306, user="root",password="mysql", database="test", charset="utf8");# 获取游标,执行sqlcursor = conn.cursor();sql = "select * from books";# 执行sql'''如果sql为查询语句,返回为查询结果集;如果为增删改,返回为受影响行数'''result = cursor.execute(sql);#fetchall获得查询结果元组result = cursor.fetchall();for book in result:id = book[0];name = book[1];path = book[2];b=Book(id=id,name=name,path=path);list.append(b);print("查询完成!");return list;if __name__ == '__main__':headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36","Accept-encoding":"gzip"}# 查询mysql数据库中books表中数据books = getBooks();num=0;for book in books:if num>10:break;print(book.name+":\t"+book.path);#获取每本小说所有章节并存入数据库getData(headers=headers,book=book);num+=1;
    

七、Flask

小技巧:创建项目,环境与代码应分开放置

1.安装flask和pymysql

pip install flask pymysql -i https://mirrors.aliyun.com/pypi/simple

2. Flask入门

  • 是Python的Web的微型框架,核心实现Web服务()的WSGI规范。包含了jinja2的模板技术

  • flask只实现了核心功能,对于数据库操作需要自己实现。

  • 解决8.0无法远程连接:
    mysql> use mysql;
    mysql> select user,host from user;
    user ,   host
    root,    localhost   # 不能远程连接的,必须是本地连接
    mysql> update user set host='%' where user='root' and            host='localhost';
    mysql> grant all privileges on *.* to 'root'@'%';
    mysql> flush privileges;
    
  • 快速入门

    • alt insert 创建文件快捷键
    • static 静态文件夹
    • templates 模板文件 选择template
  • flask服务的入口

"""
Flask 服务的入口脚本
"""
import jsonfrom flask import Flask,make_response,render_template,request
#导包 DB
from db import DB
#导包
from spider_book import get_book
#ctrl+p(ctr+鼠标)显示方法参数
app = Flask(__name__,static_url_path="/s",static_folder="static")#声明站点的主页资源(动态资源)
@app.route('/' , methods=['Get'])#装饰器---java的注解
def index_handle():# 当实例对象使用with 进入上下文时,会调用对象的__enter__方法# 当实例退出上下文时,会调用对象的__exit__方法with DB() as c:c.execute('select * from books')ret = list(c.fetchall())return render_template('index.html',title="我是书库",books=ret)@app.route('/search',methods=['GET','POST'])
def search_handle():# GET 请求   获取资源# POST 请求  上传资源# flask.request 对象存储了客户端请求过来的相关数据(请求报文中提取)kw = request.form.get('kw','');#是字典格式ret=None;if request.method == 'POST':#   处理搜索功能#   读取表单数据中的kw字段值sql ="""select * from bookswhere b_name like %s"""with DB() as c:# If args is a list or tuple, %s can be used as a placeholder in the query.# If args is a dict, %(name)s can be used as a placeholder in the query.c.execute(sql,args=(f'%{kw}%',))ret = list(c.fetchall())return render_template('search.html',kw=kw,results=ret)@app.route('/spider',methods=['GET'])
def spider_handle():#   获取请求参数pathpath = request.args.get("path")#   根据path获取bookbook=get_book(path)#json.dumps() 将dict或list对象转为json格式的字符串# json格式: 对象{"key":"value"...},数组:[{},{}]# resp_data  = json.dumps({'code':100,'msg':'OK'})resp_data = json.dumps(book)response = make_response(resp_data)response.headers['Content-Type'] = 'application/json;charset=utf-8'return response #返回json数据#渲染# return render_template("book.html",book=book)if __name__ == '__main__':app.run(host="0.0.0.0",port=5000,debug=True)
  • 数据库的工具类
from pymysql import Connect
from pymysql.cursors import DictCursor
# 进入到mysql客户端
"""
mysql> use mysql;
mysql> select user,host from user;
user ,   host
root,    localhost   # 不能远程连接的,必须是本地连接mysql> update user set host='%' where user='root' and host='localhost';
mysql> grant all privileges on *.* to 'root'@'%';
mysql> flush privileges;
"""
DB_CONFIG = {#180.76.121.47'host':'127.0.0.1',#3307'port':3306,'user':'root',#root'password':'mysql','db':'test','charset':'utf8'
}class DB:def __init__(self):# **xx  把xx转换成对应的关键字self.conn =Connect(**DB_CONFIG,cursorclass=DictCursor)print('--数据库连接成功!--')def __enter__(self):#进入上下文的方法,当前实例在with中使用return self.conn.cursor()   #返回游标实例def __exit__(self, exc_type, exc_val, exc_tb):#退出上下文方法,当前实例在退出with上下文时if exc_type:#执行sql出现的异常#回滚事务self.conn.rollback()print('--->db_error:',exc_val)else:#sql执行成功的#提交事务self.conn.commit()return True #True 异常已内部消化. False:异常继续抛出def create_db(self,name):with self as c:c.execute(f'create database {name} charset utf8')def create_table(self,table_name,*fields):# fields ->('id integer','name varchar(20) ')with self as c:sql = 'create table %s (%s)'field_args=','.join(fields)c.execute(sql%(table_name,field_args))
if __name__ == '__main__':# 当实例对象使用with 进入上下文时,会调用对象的__enter__方法# 当实例退出上下文时,会调用对象的__exit__方法with DB() as c:# c.execute("show tables")c.execute('desc books')for row in c.fetchall():print(row)#创建数据库或者表db=DB()# db.create_db('group1');# db.create_table('',('','',''))

书城网站首页

动态获取的浏览器驱动下载

有任何问题,欢迎私信我~

【实训总结】Python从入门到前端知识小结,再到Flask框架搭建在线书城~相关推荐

  1. 头歌实训之python字典入门

    第一关 字典 本关的编程任务是:通过重新创建上面的字典,将内容评级映射到相应的数字:{'4+': 4433, '9+': 987, '12+': 1155, '17+': 622}.具体要求如下: 将 ...

  2. 计算机专业实训日志-python有关

    第一天的和第二天的第一段因为之前没有用Word敲下来而是直接写在实训日志本上的所以这里就没有了. 第二天 12.01 第二节课讲了python中的函数,python中的函数和其他语言的函数有些不同,如 ...

  3. 【西北工业大学】程序设计实训(python)

    程序设计实训(python) 寻找水仙花数 寻找完美数 百钱百鸡问题 最大公约数和最小公倍数 回文数 素数 约瑟夫环问题 万年历 两地之间距离计算 计算 Fibonacci 序列的值 摩斯码生成器 词 ...

  4. ArcGIS Pro地理空间数据处理完整工作流实训及python技术融合深度

    [原文]:ArcGIS Pro地理空间数据处理完整工作流实训及python技术融合深度应用 <第一章.ArcGIS Pro基础 >: ArcGIS Pro 安装与配置 ArcGIS Pro ...

  5. unicode 编码转换漏洞_好程序员Python教程之字符串编码知识小结

    好程序员Python教程之字符串编码知识小结,提及Python字符串,你会想到什么?是ASCII,还是Unicode?他们之间是如何转换的?字符串编码和字符串有什么区别?接下来好程序员Python教程 ...

  6. python编码转换语句_好程序员Python教程之字符串编码知识小结

    好程序员Python教程之字符串编码知识小结,提及Python字符串,你会想到什么?是ASCII,还是Unicode?他们之间是如何转换的?字符串编码和字符串有什么区别?接下来好程序员Python教程 ...

  7. 开发了一款基于 Flask 框架的在线电影网站系统(附 Python 源码)

    文章目录 前言 项目介绍 源码获取 运行环境 安装依赖库 项目截图 首页展示图 视频展示页 视频播放页 后台管理页 整体架构设计图 项目目录结构图 前台功能模块图 后台功能模块图 本地运行图 前言 今 ...

  8. [python]用flask框架搭建微信公众号的后台

    用flask框架搭建微信公众号的后台 最近用python写了点爬虫,为了要让爬取的数据能够随时显示在我眼前,并实时根据我的指令返回数据.于是采用微信公众号做这个显示窗口,既能发送指令也能显示简单的相关 ...

  9. Python+Flask框架搭建可视化网站

    Python+Flask框架搭建可视化网站 一.项目结构 二.app.py from flask import Flask,render_template import sqlite3app = Fl ...

最新文章

  1. 《你要么出众,要么出局》读书笔记
  2. 如何找回由于IO设备错误移动磁盘的文件
  3. The Swift Code之UITextField的使用,及事件委托
  4. MFC控件的绘制与响应顺序——ZOrder
  5. linux lynx 源码,Lynx字符浏览器移植
  6. STM32 之八 在线升级(IAP)超详细图解 及 需要注意的问题解决
  7. javascript杂记
  8. .net core image怎么保存_C# 将PDF转为多种Image图像文件格式(Png/Bmp/Emf/Tiff)
  9. centos 卸载软件_Linux服务器运维必备技能 软件包和启动项超详细整理
  10. SQL SERVER 2000 创建挂起的文件操作 解决方法
  11. 手把手教程 Sublime Text 删除重复行
  12. cass连接复合线命令 lisp_在cass中如何使两个多段线合为一条
  13. 使用WebPack构建UMD库兼容性原理浅谈
  14. php 微信公众号关注推送欢迎语
  15. java毕业设计选题基于JavaWeb实现疫情环境下校园宿舍|寝室管理系统
  16. AC|崔丽/任斌在拉曼光谱结合深度学习识别病原菌胞外囊泡
  17. 预测移动用户人口属性的Kaggle竞赛作品解析
  18. ppt能转为html文件吗,请问如何能够实现将PPT分页转成HTML文件?
  19. 【2023年最新版】渗透测试入门教程,手把手带你进阶渗透测试工程师,学完即可就业
  20. 74HC595芯片介绍和使用详解【干货】

热门文章

  1. TCP/IP 主要报文头格式
  2. conda查看版本包命令
  3. 国外聊天工具下载网址
  4. Java中如何打印出一个数组中所有元素呢?
  5. Python数据分析入门--线性规划和非线性规划学习笔记
  6. python关于图像去雾
  7. 【NO ST-LINK Detected】解决办法
  8. AsyncTask 的参数
  9. mac浏览器没有网络,通讯软件(QQ、微信、飞书等)正常
  10. android面试自我介绍范文,2022年Android技术下半场在哪