Python爬虫入门教程 Python爬虫摆脱控制台,开始走上台面

418 阅读10分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第30天,点击查看活动详情

写在前面

对于一个程序猿来说,或者对于一个Python程序猿来说,你写的爬虫最后是一个python文件,传播起来毫无问题,但是你想让更多的人使用你的爬虫程序,让你的程序普适性更强,你就不能给用户一个Python文件,然后告诉他,你先安装Python环境,在扩展包,在不拉不拉,我想这样你的程序也不会有人使用了

接下来,我们将用5篇左右的博客,让大家把爬虫写的更加普遍化,后续的代码,不一定是最优的代码写法,逻辑也不一定是最优秀的代码,更多的是为了让大家将自己的爬虫“发扬光大”,让你身边的人用上你写的爬虫,当然,具备一点点的扩展性就更好了

桌面程序

没错,我们一上来就要写的是桌面程序,也就是.exe程序,该功能用到了一个Python GUI库tkinter 我们先简单的把他过一遍,当然,作为爬虫百例教程,即使学习tkinter 也要来个跟爬虫相关的东西,今天我们就实现一个最简单的,输入任意一个网页,点击下载,下载里面所有的图片

图形用户界面(Graphical User Interface,简称 GUI)

原型图如下(原型用AXURE画的,见谅~) python爬虫百例教程

画出程序的界面来

由于前段时间做了一年左右的自考相关课程,每天搞C++,操作系统,数据结构,头大了,Python环境都找不到啦~所以,需要简单配置一下Python的可用环境

pip list确定pip可用 python爬虫百例教程 python 3.7 版本 python爬虫百例教程 OK,毫无问题,赖以谋生的本领还在,接下来,继续吧 对于tkinter,可能比较陌生,不过还好,它就是一个Python模块,上手比较容易,不会也没事,打开一个官网文档,扫两眼,看看即可 docs.python.org/zh-cn/3/lib…,为何扫两眼即可,因为这文档好啊,对于初学者,压根不知道说的是啥?

有人肯定问,为什么这么多GUI库,要选择 tkinter 呢?还不是因为这是Python自带的,而且还简单... ,当然很多人也在吐槽说不好用,其实作为学习无所谓的,everything is right,况且 tkinter 也没有那么烂,整体还是不错的。

在控制台运行命令python -m tkinter 如下图所示,表示没啥毛病,可以撸代码了

python爬虫百例教程python爬虫百例教程 上来先写两行代码练练手,恩,上头了,还是写Python有意思

import tkinter
# from tkinter import Tk

# 创建主窗口
win = tkinter.Tk()
# 设置标题
win.title("抓图小程序")

# 进入消息循环,可以写控件

win.mainloop()

python爬虫百例教程 python爬虫百例教程 你看当这个窗口实现了,按照我的常规套路,这个项目其实已经做完了,哈哈

接下来,窗口有点小,调调

from tkinter import Tk

# 创建主窗口
win = Tk()
# 设置标题
win.title("抓图小程序")
win.geometry('500x300') # 注意这个x是字母x
# 进入消息循环,可以写控件
win.mainloop()

运行结果如下,为何画两条直线呢?这就有点门道了,注意看win.geometry('500x300') 这句代码,如果我修改一下,调整成下述内容

win.geometey('500x300+200+400') # 参照下图

![python爬虫百例教程 python爬虫百例教程](img-blog.csdnimg.cn/20200320232… =500x) ![python爬虫百例教程 python爬虫百例教程](img-blog.csdnimg.cn/20200320233… =500x) 具体内容不解释,自己猜

接下来,我们让其实现居中显示在屏幕中央,逻辑比较简单,就是获取分辨率,然后加减乘除一通计算即可

from tkinter import Tk

# 创建主窗口
win = Tk()
# 设置标题
win.title("抓图小程序")

# 窗体大小设置
width = 500
height = 400
# 获取屏幕分辨率
screen_width = win.winfo_screenwidth()
screen_height = win.winfo_screenheight()
position = f"{width}x{height}+{(screen_width-width)/2:.0f}+{(screen_height-height)/2:.0f}"
win.geometry(position)
# win.geometry('500x300+200+400')
# 进入消息循环,可以写控件
win.mainloop()

绘制输入框和按钮

绘制UI的时候,需要学习和补充的知识点有控件的简单用法,控件就是指的按钮,文本框等,控件的布局,代码如下

#from tkinter import Tk
import tkinter as tk
# 创建主窗口
win = tk.Tk()
# 设置标题
win.title("抓图小程序")

# 窗体大小设置
width = 500
height = 400
# 获取屏幕分辨率
screen_width = win.winfo_screenwidth()
screen_height = win.winfo_screenheight()
position = f"{width}x{height}+{(screen_width-width)/2:.0f}+{(screen_height-height)/2:.0f}"
win.geometry(position)
# win.geometry('500x300+200+400')
# 进入消息循环,可以写控件

# 创建提示文本
lb = tk.Label(win, text='请输入网址:')
# 创建文本框
entry = tk.Entry(win,width=30) # width 设置输入框的宽度,以字符为单位,默认值是20
# 创建按钮
btn = tk.Button(win,text = '分析下载')
# 创建一个多行文本框
t = tk.Text(win, width=60,height=20)

lb.grid(row=1,column=0,padx=10,pady=20)
entry.grid(row=1,column=1,pady=20)
btn.grid(row=1,column=2,padx=10,pady=20)
t.grid(row=2,column=0,padx=20,columnspan=3)
win.mainloop()

以上代码出现的效果图如下 Python爬虫入门教程 tkinter基于以上代码的简单入门,说明如下

  1. tk.Labeltk.Entrytk.Buttontk.Text 对应的是各种不同的组建,他们都是函数,都包含很多参数,拿一个举例子如下

tk.Label(win,text='提示文字:',font=('黑体',20),bg='black',width=10,height=8) 其中第一个参数win,表示tk对象,这个无歧义 text 表示Label显示的文字 font 字体和大小元组 width 宽度,字符为单位 height 高度,字符为单位,啥叫字符单位,很简单,10个表示有10个字符 在这里插入图片描述

接下来是一段添加控件和布局相关的代码

lb.grid(row=1,column=0,padx=10,pady=20)
entry.grid(row=1,column=1,pady=20)
btn.grid(row=1,column=2,padx=10,pady=20)
t.grid(row=2,column=0,padx=20,columnspan=3)

在tkinter中有三种控件布局方式

  • place
  • pack
  • grid

每种布局都有独特的代码写法,以下我简单进行说明,如果深挖,建议搜索引擎走起,好好搞搞

  1. pack 布局

参数如下 after: 将组件置于其他组件之后; before: 将组件置于其他组件之前; anchor: 组件的对齐方式,顶对齐'n',底对齐's',左'w',右'e' side: 组件在主窗口的位置,可以为'top','bottom','left','right'(使用时tkinter.TOP,tkinter.LEFT); fill: 填充方式 (Y,垂直,X,水平,BOTH,水平+垂直),是否在某个方向充满窗口 expand:1可扩展,0不可扩展,代表控件是否会随窗口缩放

看一下效果,然后实操的时候,你应该会碰到更多的坑,碰到想办法解决即可,编程的乐趣就是与BUG斗法!

from tkinter import *

root = Tk()
w = Label(root, text="red", bg="red", fg="white")
w.pack(padx=5, pady=10, side=LEFT)
w = Label(root, text="green", bg="green", fg="black")
w.pack(padx=5, pady=20, side=LEFT)
w = Label(root, text="blue", bg="blue", fg="white")
w.pack(padx=5, pady=20, side=LEFT)

mainloop()

Python爬虫入门教程 2. place布局

这个比较简单了,就是按照坐标系进行布局,坐标系原点是窗口的左上角 anchor: 组件对齐方式;n, ne, e, se, s, sw, w, nw, or center ; ('n'==N) x: 组件左上角的x坐标; y: 组件左上角的y坐标; relx: 组件左上角相对于窗口的x坐标,应为0-1之间的小数;图形位置相对窗口变化 rely: 组件左上角相对于窗口的y坐标,应为0-1之间的小数; width: 组件的宽度; heitht: 组件的高度; relwidth: 组件相对于窗口的宽度,0-1之间的小数,图形宽度相对窗口变化; relheight:  组件相对于窗口的高度,0-1之间的小数;

  1. grid表格布局

该布局方式类似HTML中的DIV+CSS布局,作为一个老前端工程师,我比较喜欢这个布局方式,不过对初学者来说,不是很友好 column: 组件所在的列起始位置;
columnspan: 组件的列宽;跨列数 row:组件所在的行起始位置; rowspan: 组件的行宽;rowspam=3 跨3行 sticky:对齐方式:NSEW(北南东西)上下左右
padx、pady x方向间距、y方向间距(padx=5)

如果你英语底子不错,下面的三个文章,可以好好读读

effbot.org/tkinterbook…
effbot.org/tkinterbook…
effbot.org/tkinterbook…

触发按钮事件

布局完毕,下面实现点击按钮,获取文本框中输入的网址 python爬虫教程 首先在按钮声明的函数中添加新的参数 btn = tk.Button(win,text = '分析下载', command=down_img) command 绑定触发函数

获取本文框内容

# 事件函数
def down_img():
    # print("hello world")
    # 获取文本框内容
    url = entry.get()
    analyse(url)

当你写到这里之后,剩下的只是爬虫和页面数据显示的问题了。

补全爬虫代码

按照拿到链接获取代码的方式,我们把代码补全,当然这个地方只做最基本的演示,没有做异步调用等功能,后续我们在逐步完善

爬虫代码补充完毕之后,代码长成下面的样子,下载网页的链接,我使用的是 https://cn.chinadaily.com.cn/a/202003/24/WS5e79839aa3107bb6b57a8652.html

#from tkinter import Tk
import tkinter as tk
import requests
import re
import time
# 创建主窗口
win = tk.Tk()
# 设置标题
win.title("抓图小程序")

# 窗体大小设置
width = 500
height = 400
# 获取屏幕分辨率
screen_width = win.winfo_screenwidth()
screen_height = win.winfo_screenheight()
position = f"{width}x{height}+{(screen_width-width)/2:.0f}+{(screen_height-height)/2:.0f}"
win.geometry(position)
# win.geometry('500x300+200+400')
# 进入消息循环,可以写控件

# 通用页面headers
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36",
    "Referer":"https://img3.chinadaily.com.cn"
}

# 创建提示文本
lb = tk.Label(win, text='请输入网址:')
# 创建文本框
entry = tk.Entry(win,width=30) # width 设置输入框的宽度,以字符为单位,默认值是20
# 创建一个多行文本框
t = tk.Text(win, width=60,height=20)

# 下载图片
def save_img(img):
    #t.insert("insert", f"下载中\n")
    # 拼接URL

    img = img if img.find('http')==0 else "http:"+img
    try:
        response = requests.get(img,headers=headers)
        ctx = response.content
        with open(f'./{time.time()}.jpg', 'wb') as f:
            f.write(ctx)
    except Exception as e:
        print(e.args)

# 分析网页图片清单
def analyse(url):
    resp = requests.get(url,headers=headers)
    content = resp.text # 获取到网页内容
    #print(content)
    imgs = re.findall('img src="(.*?)"', content)
    # 界面展示获取到的图片数量

    t.insert("insert", f"获取到{len(imgs)}张图片\n")
    t.insert("insert", f"开始下载图片...\n")
    for img in imgs:
        save_img(img)
    t.insert("insert", f"下载完毕\n")



# 事件函数
def down_img():
    # print("hello world")
    # 获取文本框内容
    url = entry.get()
    analyse(url)

# 创建按钮
btn = tk.Button(win,text = '分析下载', command = down_img)


lb.grid(row=1,column=0,padx=10,pady=20)
entry.grid(row=1,column=1,pady=20)
btn.grid(row=1,column=2,padx=10,pady=20)
t.grid(row=2,column=0,padx=20,columnspan=3)

win.mainloop()

假如前面的博客你是一篇一篇看到这里来的,那么这段代码是非常简单的,就不在做过多的说明。 关于tkinter里面涉及的一个点就是多行文本框插入文本,这个随意百度一下很多内容。

完善软件界面

python爬虫百例教程

添加软件运行图标

现在这个软件已经基本已经成型,修改一下左上角的软件图标,这个地方一般用.ico图标 你可以打开 www.easyicon.net/language.en… 找一个你喜欢的图标,记得下载ico图标 代码也非常简单,把下载好的ico图标放置到根目录

win.iconbitmap('./spider.ico')

剩余的两种方法,不在涉及,可自行检索 iconphoto()tk.call()

打包成exe程序,用来分享

接下来通过 pip install pyinstaller 安装一下 打包程序,然后通过下面的命令生成exe程序 Python爬虫入门教程 注意打包的时候,如果程序中设置了软件图标,那么打包的时候,需要调整的代码较多,这个我们后续在讨论 为了打包便携,我们删除图标设置部分代码,这部分没有展开,记得安装了 pip install pyinstaller 之后,我们还是在 Scripts文件夹里面进行的操作

pyinstaller -F D:\python100\newsimg.py --noconsole

打包之后,如下 Python爬虫入门教程

写在后面

本篇博客,主要是给你一个非常非常简单的小案例,用于将自己的python爬虫进行打包,后续博客中,我们还将顺着这条思路走下去。

happy ending ...