爬虫_tkinter_import

文章未经允许,不可转载

文章的大部分内容为Python代码,所以不建议在手机上阅读

写在前面

快一个月没有写任何文章了,写文章会上瘾,原来不写文章也会,:)。
这篇文章随便写写,不涉及任何深奥的技术知识,当然还是需要Python基础。文章的大致内容:

  1. 写一个小小的爬虫,很小的那种,:)
  2. 用tkinter将爬虫的结果做一个展示
  3. 谈谈tkinter中涉及到的import知识,还有import延伸内容,欢迎讨论
    • 不要觉得import很难,但是它确实让人困惑
    • 可以结合之前的文章看看习惯写if __name__ == ‘__main__‘,这篇文章是从多进程的角度写的,也很有意思

      爬虫

      爬虫的目标是得到我厨和易果生鲜网站下的美国红蛇果的价格,本次爬虫涉及到的技能,以前的文章全部涉及,比如简单网站爬虫的所有技能。所以关于爬虫的代码,不会有详细的注释。

注:如果你想学习爬虫,这个网站关于爬虫的文章,应该不会让你失望。

爬取我厨

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -*- coding: utf-8 -*-

__author__ = 'duohappy'

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36'}

def get_wochu_price(url):

web_source = requests.get(url, headers= headers)
web_source.encoding = 'utf-8'

web_data = web_source.text

soup = BeautifulSoup(web_data, 'lxml')

title_tag = soup.select('div.goods-info div.good-name')[0]
price_tag = soup.select('div.price-view div.price span')[0]

return (title_tag.text, price_tag.text) # 返回一个元组


if __name__ == '__main__':
url = 'http://www.wochu.cn/Product/Deatail/349adbd3-9b10-4b60-97d9-fec13c9a56e5'
get_wochu_price(url)

爬取易果生鲜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -*- coding: utf-8 -*-

__author__ = 'duohappy'

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36'}

def get_yiguo_price(url):

web_source = requests.get(url, headers= headers)
web_source.encoding = 'utf-8'

web_data = web_source.text

soup = BeautifulSoup(web_data, 'lxml')

title_tag = soup.select('div.product-info div.summary-name h1')[0]
price_tag = soup.select('div.pro-price div span strong')[0]

return (title_tag.text, price_tag.text) # 返回一个元组


if __name__ == '__main__':
url = 'http://www.yiguo.com/product/1294029.html'
get_yiguo_price(url)

tkinter

简单的gui,用tkinter挺好的,Python原生自带,学起来也不复杂,组件、布局、事件。
对于Python3来说不是Tkinter,而是tkinter,注意大小写

gui源代码

可能需要一点tkinter基础

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# -*- coding: utf-8 -*-

__author__ = 'duohappy'

# 导入tkinter包
import tkinter as tk

# 导入相关爬虫函数
from wochu_price import get_wochu_price
from yiguo_price import get_yiguo_price

root = tk.Tk() # 建立主窗体
root.title('Have Fun') # 设置窗体标题
root.geometry('600x200') # 设置窗口大小
root.resizable(width=True, height=True) # 窗口是可变大小的

frame_top = tk.Frame(root) # 在主窗体上建立一个frame
frame_mid = tk.Frame(root)
frame_bottom = tk.Frame(root)
frame_top.pack() # 显示出frame
frame_mid.pack()
frame_bottom.pack()

tk.Label(frame_top, text='美国红蛇果').pack() # 建立label并显示出来
tk.Label(frame_mid, text='我厨').grid(row=0, pady=10) # 上面使用pack
tk.Label(frame_mid, text='易果生鲜').grid(row=1, pady=10) # 现在使用grid,目的是为了布局更加方便

wochu_price_var = tk.StringVar() # 创建价格变量
wochu_title_var = tk.StringVar() # 创建标题变量
wochu_price_entry = tk.Entry(frame_mid, textvariable=wochu_price_var, width=6) # 创建一个显示条
wochu_title_entry = tk.Entry(frame_mid, textvariable=wochu_title_var, width=50)
wochu_price_entry.grid(row=0, column=1, padx=10) # 进行布局
wochu_title_entry.grid(row=0, column=2, padx=10)

yiguo_price_var = tk.StringVar()
yiguo_title_var = tk.StringVar()
yiguo_price_entry = tk.Entry(frame_mid, textvariable=yiguo_price_var, width=6)
yiguo_title_entry = tk.Entry(frame_mid, textvariable=yiguo_title_var, width=50)
yiguo_price_entry.grid(row=1, column=1)
yiguo_title_entry.grid(row=1, column=2)

def spider_price():
wochu_url = 'http://www.wochu.cn/Product/Deatail/349adbd3-9b10-4b60-97d9-fec13c9a56e5'
yiguo_url = 'http://www.yiguo.com/product/1294029.html'

wochu_title, wochu_price = get_wochu_price(wochu_url) # 拆包
yiguo_title, yiguo_price = get_yiguo_price(yiguo_url)

wochu_title_var.set(wochu_title)
wochu_price_var.set(wochu_price)

yiguo_title_var.set(yiguo_title)
yiguo_price_var.set(yiguo_price)

tk.Button(frame_bottom, text='spider',
command=spider_price, padx=10, pady=10).pack() # 按钮上绑定了一个函数,点击按钮执行spider_price函数

root.mainloop() # 窗体循环

最后的样子

可能简单,但是不妨碍有趣
tkinter

import

为什么突然想到写import相关的内容,因为学了tkinter。这个包很容易让没有学好import的人困惑(包括现在的我),我遇到了关于tkinter包的问题,在网上搜索后发现没什么正确的回答,所以我来写写看。

不写from import 和import最常见的区别,只写点延伸内容

tkinter的messagebox

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# -*- coding: utf-8 -*-

__author__ = 'duohappy'

# 虽然一般不推荐from ... import * 这种写法
# 但是对于tkinter这个包,一般还真是这么写
from tkinter import *

# 令人困惑的地方是既然from tkinter import *
# 把所有的内容都导入了
# 为什么还要单独import messagebox
# 网上很多这样的问题,没有加这条语句,直接写tk.messagebox或者messagebox
# 结果都是运行失败!
from tkinter import messagebox

def callback():
if messagebox.askyesno('Sundy', 'HI'):
print('click yes')
else:
print('click no')


root = Tk()

button1 = Button(root, text='button1', command=callback)
button1.pack()

root.mainloop()

原因应该是在…Lib\tkinter中的__init__.py文件里,读一读这个文件

chardet中的UniversalDetector

chardet是一个非常优秀的编码识别模块,当初学习这个模块的时候,自己还真是被import相关知识给困惑了一番。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# -*- coding: utf-8 -*-
__author__ = 'duohappy'

import chardet

def simpleUsage():
with open('./test.txt','rb') as f:
detect_result = chardet.detect(f.read())
print(detect_result)


# 没有出错!!
# 2017年6月28日,我才知道chardet.universaldetector.UniversalDetector()不会报错了
# 旧版的chardet可是会报错的
# 不知道有没有用过chardet旧版的朋友,:)
def advancedUsage():
detector = chardet.universaldetector.UniversalDetector()
with open('./test.txt','rb') as f:
for line in f.readlines():
detector.feed(line)
if detector.done:
break
detector.close()
print(detector.result)

if __name__ == '__main__':
simpleUsage()
advancedUsage()

以前的经典写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# -*- coding: utf-8 -*-

__author__ = 'duohappy'

# 这样导入包后,没有报错了
from chardet.universaldetector import UniversalDetector

def advancedUsage():
detector = UniversalDetector()
# with 语句来打开文件,推荐
with open('./test.txt','rb') as f:
# f.readlines()是可以用于迭代的
# 调用 readlines 方法,把整个文件读入内存并把内容拆分成 string 列表
for line in f.readlines():
detector.feed(line) # 帮助文档
if detector.done: # 如果已经到了置信标准,则detector.done被赋值为True
break # 那么循环没有必要继续
detector.close() # 关闭检测器
print(detector.result)

if __name__ == '__main__':
advancedUsage()

chardet更新了什么?答案应该还是在__init__.py里,去看看?如果你看了tkinter中的__init__.py的话,可能会发现点什么。

有趣的事情

test.py

1
2
3
4
5
print('hello')
x = 10

def foo():
print(x)

test1.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
x = 12
print(x)
from test import x, foo
print(x) # 10,不是12了
foo() # 10

x = 20 # 修改了x
foo() # 但是对test.py的x无效

'''
12
hello
10
10
10
'''

拓展阅读

import-confusion,这篇文章写于1999年,现在读来,依然受益匪浅!谢谢作者,:)

写在后面

以后会陆续开始写SQL、数据挖掘相关的文章,感谢你的阅读。

您的支持将鼓励我继续创作!