唤醒手腕Python爬虫学习笔记

1、基础语法知识点

字符串的分割

  1. webString = 'www.baidu.com'
  2. print(webString.split('.'))
  3. # ['www', 'baidu', 'com']

字符串前后空格的处理,或者特殊字符的处理

  1. webString = ' www.baidu.com '
  2. print(webString.strip())
  3. # www.baidu.com
  4. webString = '!*www.baidu.com*!'
  5. print(webString.strip('!*'))
  6. # www.baidu.com

字符串格式化

  1. webString = '{}www.baidu.com'.format('https://')
  2. print(webString)
  3. # https://www.baidu.com

自定义函数

  1. webString = input("Please input url = ")
  2. print(webString)
  3. def change_number(number):
  4. return number.replace(number[3:7], '*'*4)
  5. print(change_number("15916881234"))
  6. # 159****1234

python文件通常有两种使用方法:

第一是作为脚本直接执行。

第二是 import 到其他的 python 脚本中被调用(模块重用)执行。

因此 if __name__ == 'main' 的作用就是控制这两种情况执行代码的过程,在 if __name__ == 'main' 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行。

2、基本爬虫操作

网络请求加密方式:1. 对称密钥加密 2. 非对称密钥加密 3.证书加密(https)

首先安装request第三方的库
唤醒手腕Python网络爬虫学习笔记 - 图1

GuessedAtParserWarning: No parser was explicitly specified 未添加解析器

基本请求的案例

  1. import requests
  2. link = "http://www.santostang.com/"
  3. headers = {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'}
  4. data = requests.get(link, headers=headers)
  5. print(data.text)

完整代码展示

  1. import requests
  2. from bs4 import BeautifulSoup
  3. link = "http://www.santostang.com/"
  4. headers = {
  5. 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'}
  6. data = requests.get(link, headers=headers)
  7. soup = BeautifulSoup(data.text, "html.parser")
  8. print(soup.find("h1", class_="post-title").a.text)
  9. # 第四章 – 4.3 通过selenium 模拟浏览器抓取

数据持久化的操作,写入文件中

  1. with open('index.txt', 'w+', encoding="utf-8") as f:
  2. f.write(text)
  3. f.close()

3、数据持久化储存

如果发生写入文件的字符出现乱码,那么需要增加 encoding=”utf-8

文件操作的基础模式有三种(默认的操作模式为r模式):

  • r 模式为 read
  • w 模式为 write
  • a 模式为 append

文件读写内容的格式有两种(默认的读写内容的模式为b模式):

  • t 模式为 text
  • b 模式为 bytes

常见的文件打开模式:

  1. r:只读模式,文件的指针放在文件开头
  2. w:只写模式,文件不存在则创建,文件存在,则覆盖原有内容,文件指针在文件开头
  3. a:追加模式打开文件,文件不存在则创建,文件指针在开头,文件存在则在文件尾追加内容,文件指针在源文件末尾
  4. b:以二进制方式打开文件,不能单独使用,需要与其他模式一起使用,如:rbwb
  5. +:以读写模式代开文件,不能单独使用,需要与其他模式一起使用,如:a+

4、json库的使用

  1. import requests
  2. import json
  3. headers = {
  4. 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'}
  5. data = requests.get("http://localhost:8080/person/words/all", headers=headers, timeout=0.5)
  6. json_data = json.loads(data.text)
  7. for index, each_row in enumerate(json_data):
  8. print()
  9. print(str(index + 1) + '.\t' + each_row['english'].ljust(20) + each_row['chinese'])
  10. # 1. extreme adj. 极度的,极端的;n. 极端
  11. #
  12. # 2. concern n. 关心;关系;公司 vt. 涉及,有关;使担心
  13. #
  14. # 3. benefic adj. 有益的

5、selenium库的使用

定位一个元素 定位多个元素 含义
find_element_by_id find_elements_by_id 通过元素id定位
find_element_by_name find_elements_by_name 通过元素name定位
find_element_by_xpath find_elements_by_xpath 通过xpath表达式定位
find_element_by_link_text find_elements_by_link_text 通过完整超链接定位
find_element_by_partial_link_text find_elements_by_partial_link_text 通过部分链接定位
find_element_by_tag_name find_elements_by_tag_name 通过标签定位
find_element_by_class_name find_elements_by_class_name 通过类名进行定位
find_elements_by_css_selector find_elements_by_css_selector 通过css选择器进行定位

假如我们有一个Web页面,通过前端工具(如,Firebug)查看到一个元素的属性是这样的。

  1. <html>
  2. <head></head>
  3. <body link="#0000cc">
  4. <a id="result_logo" href="/" onmousedown="return c({'fm':'tab','tab':'logo'})">
  5. <form id="form" class="fm" name="f" action="/s">
  6. <span class="soutu-btn"></span>
  7. <input id="kw" class="s_ipt" name="wd" value="" maxlength="255" autocomplete="off"/>
  8. </form>
  9. </body>
  10. </html>

通过id定位:

  1. dr.find_element_by_id("kw")

通过name定位:

  1. dr.find_element_by_name("wd")

通过class name定位:

  1. dr.find_element_by_class_name("s_ipt")

通过tag name定位:

  1. dr.find_element_by_tag_name("input")

通过xpath定位,xpath定位有N种写法,这里列几个常用写法:

  1. dr.find_element_by_xpath("//*[@id='kw']")
  2. dr.find_element_by_xpath("//*[@name='wd']")
  3. dr.find_element_by_xpath("//input[@class='s_ipt']")
  4. dr.find_element_by_xpath("/html/body/form/span/input")
  5. dr.find_element_by_xpath("//span[@class='soutu-btn']/input")
  6. dr.find_element_by_xpath("//form[@id='form']/span/input")
  7. dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")

通过css定位,css定位有N种写法,这里列几个常用写法:

  1. dr.find_element_by_css_selector("#kw")
  2. dr.find_element_by_css_selector("[name=wd]")
  3. dr.find_element_by_css_selector(".s_ipt")
  4. dr.find_element_by_css_selector("html > body > form > span > input")
  5. dr.find_element_by_css_selector("span.soutu-btn> input#kw")
  6. dr.find_element_by_css_selector("form#form > span > input")

接下来,我们的页面上有一组文本链接。

  1. <a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>
  2. <a class="mnav" href="http://www.hao123.com" name="tj_trhao123">hao123</a>

通过link text定位:

  1. dr.find_element_by_link_text("新闻")
  2. dr.find_element_by_link_text("hao123")

通过partial link text定位:

  1. dr.find_element_by_partial_link_text("新")
  2. dr.find_element_by_partial_link_text("hao")
  3. dr.find_element_by_partial_link_text("123")

6、jieba库的使用

jieba.cut 方法接受三个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 HMM 模型

jieba.cut 以及 jieba.cut_for_search 返回的结构都是一个可迭代的 generator,可以使用 for 循环来获得分词后得到的每一个词语(unicode)

print(*objects, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False) print不换行,print(“helloworld”,end=””)

  1. import jieba
  2. String = "My name is wrist waking"
  3. for item in jieba.cut(String):
  4. print(item, end='')
  5. String_chinese = "我的名字叫唤醒手腕"
  6. for item in jieba.cut(String_chinese, cut_all=True):
  7. print(item, end=',')
  8. # My name is wrist waking我,的,名字,叫唤,唤醒,手腕,

7、pymysql库的使用

python3 与 MySQL 进行交互编程需要安装 pymysql 库,故首先使用如下命令安装pymysql

  1. pip install pymysql
  1. import pymysql
  2. # 打开数据库连接
  3. conn = pymysql.connect(host='localhost', user="root", passwd="root", db="nodedb")
  4. print(conn)
  5. print(type(conn))

conn.cursor() : 获取游标
要想操作数据库,光连接数据是不够的,必须拿到操作数据库的游标,才能进行后续的操作,比如读取数据、添加数据。通过获取到的数据库连接实例conn下的cursor()方法来创建游标。

游标用来接收返回结果

说明:cursor返回一个游标实例对象,其中包含了很多操作数据的方法,比如执行sql语句。

执行sql语句execute和executemany

  • execute(query,args=None)
  • 函数作用:执行单条的sql语句,执行成功后返回受影响的行数
  • 参数说明:
  1. query:要执行的sql语句,字符串类型
  2. args:可选的序列或映射,用于query的参数值。如果args为序列,query中必须使用%s做占位符;如果args为映射,query中必须使用%(key)s做占位符
  • executemany(query,args=None)
  • 函数作用:批量执行sql语句,比如批量插入数据,执行成功后返回受影响的行数
  • 参数说明:
  1. query:要执行的sql语句,字符串类型
  2. args:嵌套的序列或映射,用于query的参数值

数据库性能瓶颈很大一部份就在于网络IO和磁盘IO,将多个sql语句放在一起,只执行一次IO,可以有效的提升数据库性能。

用executemany()方法一次性批量执行sql语句,固然很好,但是当数据一次传入过多到server端,可能造成server端的buffer溢出,也可能产生一些意想不到的麻烦。所以,合理、分批次使用executemany是个合理的办法。

定义数据连接操作的类

  1. # connect_db:连接数据库,并操作数据库
  2. import pymysql
  3. class OperationMysql:
  4. """
  5. 数据库SQL相关操作
  6. import pymysql
  7. # 打开数据库连接
  8. db = pymysql.connect("localhost","testuser","test123","TESTDB" )
  9. # 使用 cursor() 方法创建一个游标对象 cursor
  10. cursor = db.cursor()
  11. # 使用 execute() 方法执行 SQL 查询
  12. cursor.execute("SELECT VERSION()")
  13. """
  14. def __init__(self):
  15. # 创建一个连接数据库的对象
  16. self.conn = pymysql.connect(
  17. host='127.0.0.1', # 连接的数据库服务器主机名
  18. port=3306, # 数据库端口号
  19. user='root', # 数据库登录用户名
  20. passwd='root',
  21. db='nodedb', # 数据库名称
  22. charset='utf8', # 连接编码
  23. cursorclass=pymysql.cursors.DictCursor
  24. )
  25. # 使用cursor()方法创建一个游标对象,用于操作数据库
  26. self.cur = self.conn.cursor()
  27. # 查询一条数据
  28. def search_one(self, sql):
  29. self.cur.execute(sql)
  30. result = self.cur.fetchone() # 使用 fetchone()方法获取单条数据.只显示一行结果
  31. # result = self.cur.fetchall() # 显示所有结果
  32. return result
  33. # 更新SQL
  34. def updata_one(self, sql):
  35. try:
  36. self.cur.execute(sql) # 执行sql
  37. self.conn.commit() # 增删改操作完数据库后,需要执行提交操作
  38. except:
  39. # 发生错误时回滚
  40. self.conn.rollback()
  41. self.conn.close() # 记得关闭数据库连接
  42. # 插入SQL
  43. def insert_one(self, sql):
  44. try:
  45. self.cur.execute(sql) # 执行sql
  46. self.conn.commit() # 增删改操作完数据库后,需要执行提交操作
  47. except:
  48. # 发生错误时回滚
  49. self.conn.rollback()
  50. self.conn.close()
  51. # 删除sql
  52. def delete_one(self, sql):
  53. try:
  54. self.cur.execute(sql) # 执行sql
  55. self.conn.commit() # 增删改操作完数据库后,需要执行提交操作
  56. except:
  57. # 发生错误时回滚
  58. self.conn.rollback()
  59. self.conn.close()
  60. if __name__ == '__main__':
  61. op_mysql = OperationMysql()
  62. res = op_mysql.search_one("SELECT * from people WHERE id = 1")
  63. print(res)
  64. # {'id': 1, 'name': '周杰伦', 'age': 42}

8、mongodb数据库

MongoDB是基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

MongoDB服务端可运行在Linux、Windows或mac os x平台,支持32位和64位应用,默认端口为27017。

推荐运行在64位平台,因为MongoDB在32位模式运行时支持的最大文件尺寸为2GB。

MongoDB 主要特点

  • MongoDB中的记录是一个文档,它是由字段和值对组成的数据结构。
  • 集合就是一组文档,类似于关系数据库中的表。

既然集合中可以存放任何类型的文档,那么为什么还需要使用多个集合?

这是因为所有文档都放在同一个集合中,无论对于开发者还是管理员,都很难对集合进行管理,而且这种情形下,对集合的查询等操作效率都不高。所以在实际使用中,往往将文档分类存放在不同的集合中。

MongoDB 实例可以承载多个数据库。它们之间可以看作相互独立,每个数据库都有独立的权限控制。在磁盘上,不同的数据库存放在不同的文件中。

MongoDB 中存在以下系统数据库:

  • Admin 数据库:一个权限数据库,如果创建用户的时候将该用户添加到admin 数据库中,那么该用户就自动继承了所有数据库的权限。
  • Local 数据库:这个数据库永远不会被复制,可以用来存储本地单台服务器的任意集合。
  • Config 数据库:当MongoDB使用分片模式时,config 数据库在内部使用,用于保存分片的信息。

用户权限介绍
唤醒手腕Python网络爬虫学习笔记 - 图2

创建用户

  1. cd /www/server/mongodb/bin
  2. # mongo安装目录下的bin目录
  3. mongo
  4. # 启动mongo服务,输入命令行mongo,进入mongodb环境
  5. use admin
  6. # 切换到admin数据库
  7. # 正常情况就会报错 Error: not authorized on admin
  8. # 先鉴权登录 db.auth('root', '此处是密码')
  9. db.createUser({user: "root",pwd:"root",roles:[{ role: "readWriteAnyDatabase" , db: "DBNAME" }] })
  10. # 创建用户
  11. # 成功结果如下:
  12. Successfully added user: {
  13. "user" : "root",
  14. "roles" : [
  15. {
  16. "role" : "readWriteAnyDatabase",
  17. "db" : "admin"
  18. }
  19. ]
  20. }
  21. show users
  22. # 查看用户列表

远程联机宝塔centos系统的Mongodb数据库

进行权限的配置修改:

宝塔面板 和 服务器平台 都要开启27017的端口号
唤醒手腕Python网络爬虫学习笔记 - 图3

9、pymongo库的使用

远程连接宝塔面板的Mongodb

  1. import pymongo
  2. from datetime import datetime
  3. print(datetime.now())
  4. # username="test"
  5. # password="test"
  6. # connection=pymongo.mongo_client.MongoClient(host="192.168.10.9:27017,connect=False,username=username,password=password)
  7. # 链接服务器, 是本地服务器可不需要传入参数
  8. MongoClient = pymongo.mongo_client.MongoClient("mongodb://root:root@远程服务器IP:27017")
  9. # MongoClient = pymongo.MongoClient("mongodb://root:root@远程服务器IP:27017")
  10. # 获取数据库, 中括号中填入数据库中的名字
  11. db = MongoClient["wrist"]
  12. collection = db.zhangyan
  13. res = collection.find()
  14. for item in res:
  15. print(item.get("name"))

在Document中插入数据:

  1. collection.insert_one({'name': '唤醒手腕', 'datetime': datetime.now()})
  2. insert_many(list_of_dict) # 插入多个

比较运算符 查找数据

符号 说明
$eq 它将匹配等于指定值的值
$ne 它将匹配所有不等于指定值的值
$gt 它将匹配大于指定值的值
$gte 它将匹配所有大于或等于指定值的值
$lt 它将匹配所有小于指定值的值
$lte 它将匹配所有小于或等于指定值的值
$in 它将匹配数组中指定的任何值
$nin 它讲匹配不再数组中的值
  1. filterOption = {
  2. "age": {"$gte": 20}
  3. }
  4. # 查询年龄大于等于20岁的
  5. data = collection.find_one(filterOption)
  6. print(data)
  7. # {'_id': ObjectId('61c7297dfff4db0a50af9f06'), 'name': '张燕', 'age': 20}

逻辑运算符查询
唤醒手腕Python网络爬虫学习笔记 - 图4

  1. filterAnd = {
  2. '$and':[
  3. {'fid': {'$eq': 2048}}, # filter_01
  4. {'sid': {'$ne': 1024}} # filter_02
  5. ]
  6. }
  7. filterOr = {
  8. '$or':[
  9. {'fid': {'$eq': 2048}}, # filter_01
  10. {'sid': {'$ne': 1024}} # filter_02
  11. ]
  12. }

正则表达式查询

  1. filterOption = {
  2. 'name': {'$regex': r'Tom [a-zA-Z]+'}
  3. }

遍历文档获取集合内所有文件:

  1. # collection.find({})
  2. # collection.find_one(filter) 只返回1个
  3. for one in collection.find({}):
  4. print(one)

删除的操作:

删除一个 collection.delete_one(filter)

删除多个 collection.delete_many(filter)

修改的操作:

collection.update_many(filter, update)

新参量 update 说明:形式 {command: {key: value}}

  • $set 修改或新增字段
  • $unset 删除指定字段
  • $rename 重命名字段
  1. # 修改或新增字段
  2. filter = {'name': '马大师'}
  3. add_data = {'age': 60}
  4. # key name 存在,改其值为 马大师?
  5. update1 = {'$set': {'name': '马大师?'}}
  6. # key age 不存在,插入字段
  7. update2 = {'$set': add_data}
  8. collection.update_one(filter, update1)
  9. collection.update_one(filter, update2)
  10. # 删除指定字段
  11. filter = {'name': '马大师?'}
  12. del_data = {'age': 60}
  13. update = {'$unset': del_data}
  14. collection.update_one(filter, update)
  15. # 重命名字段
  16. filter = {'name': '马大师?'}
  17. update = {'$rename': {'name': '名字'}}
  18. collection.update_one(filter, update)

断开连接:

  1. client.close()

综合案例:

  1. import requests
  2. import json
  3. import pymongo
  4. headers = {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'}
  5. data = requests.get("http://localhost:8080/person/words/all", headers=headers)
  6. words = json.loads(data.text)
  7. MongoClient = pymongo.mongo_client.MongoClient("mongodb://root:root@远程服务器IP:27017")
  8. db = MongoClient['wrist']
  9. collection = db.word
  10. collection.insert_many(words)

唤醒手腕Python网络爬虫学习笔记 - 图5

10、媒体资源爬取

requests对象的get和post方法都会返回一个对象Response对象,在这个对象中存放的是服务器返回的所有信息,包括响应头,响应状态码等等。

  • .text 返回的是Beautifulsoup根据猜测的编码方式将content内容编码成字符串。
  • .content 返回的是bytes字节码

.text是现成的字符串,.content还要编码,但是.text不是所有时候显示都正常,这是就需要用.content进行手动编码。

关于图片资源的爬取

首先就是获取图片资源的URL地址,对地址发起请求获取二进制数据 data.content

  1. import requests
  2. url = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202005%2F12%2F20200512131057_4Rsc8.thumb.1000_0.jpeg"
  3. data = requests.get(url)
  4. with open('minitang.jpg', 'wb') as f:
  5. f.write(data.content)
  6. f.close()

关于视频资源的爬取

首先就是获取视频资源的URL地址,对地址发起请求获取二进制数据 data.content

  1. import requests
  2. url = "https://vd3.bdstatic.com/mda-mmq1yv5cag635vhm/cae_h264/1640395713342120634/mda-mmq1yv5cag635vhm.mp4"
  3. data = requests.get(url)
  4. with open("kaoyan.mp4","wb") as f:
  5. f.write(data.content)
  6. f.close()

关于音频资源的爬取

网易云音乐的接口:从这里获取id,调用http://music.163.com/song/media/outer/url?id=歌曲ID

打开网易云音乐PC端官网,搜索你想要的歌曲(举个例子:All Falls Down),在浏览器的Url地址栏,找到歌曲的id
唤醒手腕Python网络爬虫学习笔记 - 图6
代码测试如下所示:

  1. import requests
  2. import os
  3. data = requests.get("http://music.163.com/song/media/outer/url?id=515453363")
  4. with open("music.mp3", 'wb') as f:
  5. f.write(data.content)
  6. # 写入文件
  7. f.close()
  8. # 关闭文件流
  9. os.system("music.mp3")
  10. # os.system("") 调用操作系统读取打开文件

11、PIL库的使用

使用 PIL 之前需要 import Image 模块

PIL是python平台事实上的图像处理标准库,但PIL仅支持到python2.7,加上年久失修,于是在PIL的基础上创建了兼容的版本pillow,支持最新的python3.X。

然后你就可以使用Image.open(‘xx.bmp’) 来打开一个位图文件进行处理了。

打开文件你不用担心格式,也不用了解格式,无论什么格式,都只要把文件名丢给 Image.open 就可以了。真所谓 bmp、jpg、png、gif……,万物皆可斩。

  1. img = Image.open(‘origin.png’) # 得到一个图像的实例对象 img

图像处理中,最基本的就是色彩空间的转换。一般而言,我们的图像都是 RGB 色彩空间的,但在图像识别当中,我们可能需要转换图像到灰度图、二值图等不同的色彩空间。

PIL 在这方面也提供了极完备的支持,我们可以:

  1. new_img = img.convert(‘L’)

把 img 转换为 256 级灰度图像, convert() 是图像实例对象的一个方法,接受一个 mode 参数,用以指定一种色彩模式,mode 的取值可以是如下几种:

  • 1 (1-bit pixels, black and white, stored with one pixel per byte)
  • L (8-bit pixels, black and white)
  • P (8-bit pixels, mapped to any other mode using a colour palette)
  • RGB (3x8-bit pixels, true colour)
  • RGBA (4x8-bit pixels, true colour with transparency mask)
  • CMYK (4x8-bit pixels, colour separation)
  • YCbCr (3x8-bit pixels, colour video format)
  • I (32-bit signed integer pixels)
  • F (32-bit floating point pixels)

图像增强通常用以图像识别之前的预处理,适当的图像增强能够使得识别过程达到事半功倍的效果。 PIL 在这方面提供了一个名为 ImageEnhance 的模块,提供了几种常见的图像增强方案:

  1. import ImageEnhance
  2. enhancer = ImageEnhance.Sharpness(image)
  3. for i in range(8):
  4. factor = i / 4.0
  5. enhancer.enhance(factor).show("Sharpness %f" % factor)

上面的代码即是一个典型的使用 ImageEnhance 模块的例子。

SharpnessImageEnhance 模块的一个类,用以锐化图片。这一模块主要包含如下几个类:Color、BrightnessContrastSharpness,它们都有一个共同的接口 .enhance(factor),接受一个浮点参数 factor,标示增强的比例。

灰度图的制作

  1. from PIL import Image
  2. img = Image.open("../ImageMake/minitang.jpg")
  3. img = img.convert('L')
  4. try:
  5. img.save("L.jpg")
  6. except IOError:
  7. print("cannot convert")

子图片粘贴到父图片上

  1. from PIL import Image
  2. import os
  3. imgMini = Image.open('../ImageMake/L.jpg')
  4. imgMini = imgMini.resize((300, 300))
  5. imgBack = Image.open('../ImageMake/minitang.jpg')
  6. imgBack = imgBack.resize((600, 600))
  7. imgBack.paste(imgMini, (200, 200, 500, 500))
  8. try:
  9. imgBack.save("bingjie.jpg")
  10. except IOError:
  11. print("cannot save")

高斯模糊图制作

  1. from PIL import Image,ImageFilter
  2. image = Image.open("minitang.jpg")
  3. image = image.filter(ImageFilter.GaussianBlur(radius=20))
  4. try:
  5. image.save("gaoshi02.jpg")
  6. except IOError:
  7. print("cannot save")

二维码制作

首先要安装qrcode库,url可以是链接地址,也可以是文本数据。

  1. import qrcode
  2. qr = qrcode.QRCode(
  3. version=None,
  4. error_correction=qrcode.constants.ERROR_CORRECT_Q,
  5. box_size=10,
  6. border=1,
  7. )
  8. url = '巩师伟你是个傻逼!'
  9. qr.add_data(url)
  10. qr.make(fit=True)
  11. img = qr.make_image(fill_color="green", back_color="transparent")
  12. print (img.pixel_size)
  13. img.save('output2.png')

12、图像识别技术

图片的文字识别

若未安装pillow,以管理员的身份打开命令提示符,输入:pip install pillow.

例如识别如下图片中的文字,打印到控制台上:
唤醒手腕Python网络爬虫学习笔记 - 图7
代码如下所示:

  1. from PIL import Image
  2. import pytesseract
  3. im = Image.open('imgText.png')
  4. print(pytesseract.image_to_string(im, lang='chi_sim').replace('\n', ''))

运行Python文件,如果出现如下报错,错误原因是:没有安装识别引擎**tesseract-ocr**
唤醒手腕Python网络爬虫学习笔记 - 图8
tesseract-ocr : 链接:https://pan.baidu.com/s/1cu4xF8fAXfKYq71qMETeCg 提取码:5hjq

解压后,双击 tesseract-ocr-w64-setup-v4.1.0.20190314.exe 进行安装

解压安装tesseract-ocr后做如下操作,就可以支持中文识别了。因为tesseract-ocr默认不支持中文识别。
唤醒手腕Python网络爬虫学习笔记 - 图9

安装完成tesseract-ocr后,我们还需要做一下配置

打开目录:C:\Users\你的账户名称\AppData\Local\Programs\Python\Python39\Lib\site-packages\pytesseract

我的账号名称是16204,效果如下:,
唤醒手腕Python网络爬虫学习笔记 - 图10
找到pytesseract.py,打开(用pycharm打开)后做如下操作

  1. ......
  2. # tesseract_cmd = 'tesseract'
  3. # 将上面的注释,tesseract_cmd,重新赋值为你tesseract-ocr安装目录下tesseract.exe文件的地址值
  4. tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
  5. # 加r是不进行转义的意思
  6. ......

以上的操作就是:关联OCR和pytesseract

至此我们所有的配置就完成了,运行下面代码就可以解析成文字了

若出现如下的错误,先不要着急,是环境变量没有配置,我们再进行环境变量配置。

  1. pytesseract.pytesseract.TesseractError: (1, 'Error opening data file C:/Program Files/Tesseract-OCR/tessdata/chi_sim.traineddata Please make sure the TESSDATA_PREFIX environment variable is set to the parent directory of your "tessdata" directory. Failed loading language \'chi_sim\' Tesseract couldn\'t load any languages! Could not initialize tesseract.')

唤醒手腕Python网络爬虫学习笔记 - 图11
在进行系统变量配置
唤醒手腕Python网络爬虫学习笔记 - 图12
运行结果如下所示:(识别中文还是存在误差的)

  1. 唤醒ˉˉ腕你罡个 痴傻帽呀!

英文图片识别的测试

读取下面图片中的英文,打印在控制台上。
唤醒手腕Python网络爬虫学习笔记 - 图13
代码展示:

  1. from PIL import Image
  2. import pytesseract
  3. im = Image.open('imgenglish.png')
  4. print(pytesseract.image_to_string(im, lang='eng').replace('\n', ''))
  5. # lang='eng' 识别语言设置为 eng (英语)
  6. # 解释下为什么要加.replace('\n', ''),因为在文字识别时候会出现空行,所以要清除这些不必要的空行。

打印的结果如下所示:(可见英文的识别度比中文高)

  1. Time runs fast with the rapid of my heart.

13、pypiwin32库的使用

上个小节介绍了,图像识别技术,那么这个小节,介绍下智能语音朗读

需要用到的第三方库是pypiwin32,可以到pycharm的setting下安装该第三方库

  1. import win32com.client
  2. speaker = win32com.client.Dispatch("SAPI.SpVoice")
  3. speaker.Speak("唤醒手腕你真的帅呀!") # 朗读内容

运行上述的代码,可以听到智能语言朗读,不仅支持中文朗读,也支持英语朗读。

编写语音朗读闹钟功能的示例代码

首先介绍下python中关于时间的库:time,它是python环境自带的本地库,无需安装。

  1. import time
  2. currentTime = time.localtime() # 获取本地时间赋值给currentTime变量
  3. print(currentTime)
  4. # 结果:time.struct_time(tm_year=2021, tm_mon=12, tm_mday=26, tm_hour=19, tm_min=23, tm_sec=29, tm_wday=6, tm_yday=360, tm_isdst=0)

由上可见time.localtime()是有关当前系统时间的结构体。
time.struct_time.tm_year表示当前年,time.struct_time.tm_mon表示当前月······,其他表示很容易理解,不举例了。

  1. import win32com.client
  2. import time
  3. speak = win32com.client.Dispatch("SAPI.SpVoice")
  4. setUpTime = input("你要闹铃的时间(例如:19:45:40)= ")
  5. def timeFormat(value):
  6. if value >= 10:
  7. return str(value)
  8. else:
  9. return '0' + str(value)
  10. # 自定义 时间格式化函数
  11. while 1:
  12. currentTime = time.localtime()
  13. # 当前时间的纪元值
  14. currentH = timeFormat(currentTime.tm_hour)
  15. currentM = timeFormat(currentTime.tm_min)
  16. currentS = timeFormat(currentTime.tm_sec)
  17. timeShow = currentH + ':' + currentM + ':' + currentS
  18. print('当前时间:' + timeShow)
  19. if timeShow == setUpTime:
  20. speak.Speak("请注意,请注意,It's time for homework")
  21. break
  22. time.sleep(1)
  23. # time.sleep(1) 延迟1秒

14、数据可视化案例

为什么学数据可视化,对于我们在爬取到数据进行分析,那么进行数据可视化是必不可少的。如果有志于在大数据、机器学习、人工智能领域从业的话,数据可视化是首当其冲的的,因此说不得不学。

数据可视化是指通过可视化表示来探索数据,它与数据挖掘紧密相关,而数据挖掘指得是使用代码来探索数据集的规律和关联。

对于博主来说呢,博主常用Matlab进行数据可视化,我是哔哩哔哩Matlab方向的UP主,Matlab和Python都可以进行数据可视化,主要区别:Matlab比较偏向于工程计算,对于计算数学的模拟。而python来说呢,比较轻量级些,用于数据可视化是比较优越的。

数据可视化常用的第三方库:plotly、Matplotlib

如何画折线图?

  1. import matplotlib.pyplot
  2. plt = matplotlib.pyplot
  3. # 演示一下,y = x^2
  4. X_value = [1, 2, 3, 4, 5]
  5. Y_value = [1, 4, 9, 16, 25]
  6. plt.plot(X_value, Y_value)
  7. plt.show()
  8. # plt.show() 进行图像的展示

运行上述的代码,效果如下:唤醒手腕Python网络爬虫学习笔记 - 图14
对数据表格进行操作代码,展示如下(我们不需要会背,理解会用就行,后期可以查文档进行制作就行)

  1. import matplotlib.pyplot
  2. plt = matplotlib.pyplot
  3. # 演示一下,y = x^2
  4. X_value = [1, 2, 3, 4, 5]
  5. Y_value = [1, 4, 9, 16, 25]
  6. plt.plot(X_value, Y_value)
  7. plt.title("Squares Numbers", fontsize=24)
  8. # 设置标题及大小,只支持英语
  9. plt.xlabel("variable X_value", fontsize=14)
  10. # 设置x坐标名称及大小,只支持英语
  11. plt.ylabel("Function Squares of X_value", fontsize=14)
  12. # 设置y坐标名称及大小,只支持英语
  13. plt.tick_params(axis='both', labelsize=14)
  14. # 设置坐标轴上数字大小
  15. plt.legend(['X'], loc=1)
  16. # 为添加线描述;loc为描述的位置,可用数字为1-10;多个标签时为['X,'Y']类推
  17. plt.show()
  18. # plt.show() 进行图像的展示

完善信息后的图像,展示的效果如下:
唤醒手腕Python网络爬虫学习笔记 - 图15
显示中文字符:matplotlib.pyplot默认是不支持中文字符的,最简单的方法就是在代码前添加如下命令:

  1. plt.rcParams['font.sans-serif']=['SimHei']

15、matplotlib库的使用

在上个小节我们简单介绍了数据可视化简单案例,这小节我们详细去介绍matplotlib库的具体如何去使用。

matplotlib.pyplot是使matplotlib像MATLAB一样工作的命令样式函数的集合。

每个pyplot功能都会对图形进行一些更改:例如,创建图形,在图形中创建绘图区域,在绘图区域中绘制一些线条,用标签装饰绘图等。

使用pyplot生成可视化效果非常快:

  1. import matplotlib.pyplot as plt
  2. plt.plot([1, 2, 3, 4])
  3. plt.ylabel('some numbers')
  4. plt.show()
  5. # import matplotlib.pyplot
  6. # plt = matplotlib.pyplot
  7. # 上面注释的两行代码简化成 import matplotlib.pyplot as plt

展示的效果如下:
唤醒手腕Python网络爬虫学习笔记 - 图16
如果为plot()命令提供单个列表或数组 ,则matplotlib假定它是y值的序列,并自动生成x值。由于python范围从0开始,因此默认x向量的长度与y相同,但从0开始,因此x数据为 [0, 1, 2, 3]

plot()是一个通用命令,它将接受任意数量的参数。例如,要绘制x与y的关系,可以发出以下命令:

  1. plt.plot([1, 2, 3, 4], [1, 4, 9, 16])

格式化绘图样式

对于每对x,y参数,都有一个可选的第三个参数,它是表示图的颜色和线条类型的格式字符串。

格式字符串的字母和符号来自MATLAB,您将颜色字符串与线条样式字符串连接在一起。默认格式字符串是“ b-”,这是一条蓝色实线。例如,要用红色圆圈绘制以上内容,则需要编写代码如下:

  1. plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'ro')
  2. plt.axis([0, 6, 0, 20]) #[xmin, xmax, ymin, ymax]

如果matplotlib只限于使用列表,则对于数字处理将毫无用处。通常,都会使用numpy数组来配合完成。实际上,所有序列都在内部转换为numpy数组。下面的示例说明了使用数组在一条命令中绘制几行具有不同格式样式的行。

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. #numpy是python内置库,无需安装
  4. # 返回一个数组,从0到5,间距是0.25
  5. t = np.arange(0, 5, 0.25)
  6. # 红色虚线,蓝色正方形,绿色三角形
  7. plt.plot(t, t, 'r--', t, t ** 2, 'bs', t, t ** 3, 'g^')
  8. plt.show()

展示的效果如下:
唤醒手腕Python网络爬虫学习笔记 - 图17
数据可视化图片大小设置与保存

  1. import matplotlib.pyplot as plt
  2. x = range(2, 12, 2)
  3. y = [3, 6, 2, 7, 8]
  4. # 设置图片大小,像素
  5. plt.figure(figsize=(10, 4), dpi=70)
  6. # 绘制折线图,颜色为红色,线宽为2,透明度为0.5
  7. plt.plot(x, y, 'r', label='line 1', linewidth=2, alpha=0.5)
  8. # 绘制蓝色点
  9. plt.plot(x, y, 'bo')
  10. # 保存图片 当前目录下的image.png
  11. plt.savefig("./image.png")
  12. # 显示图片
  13. plt.show()

展示的效果如下:
唤醒手腕Python网络爬虫学习笔记 - 图18

16、数据分析词云图

如何用python进行数据分析,制作词云图,比如下面这只“猪”
唤醒手腕Python网络爬虫学习笔记 - 图19
我们把构建词云分为两步:

1、处理文本数据

在生成词云时,wordcloud默认会以空格或标点为分隔符对目标文本进行分词处理。

对于中文文本,分词处理需要由用户来完成。一般步骤是先将文本分词处理,然后以空格拼接,再调用wordcloud库函数。

2、产生词云图片

wordcloud库的核心是WordColoud 类,所有的功能都封装在WordCloud 类中。

使用时需要实例化一个WordCloud 类的对象,并调用其generate(text)方法将text文本转化为词云。

处理文本数据

jieba支持三种分词模式:

  1. 精确模式lcut(),试图将句子最精确地切开,适合文本分析,单词无冗余;
  2. 全模式lcut(s, cut_all=True),把句子中所有的可以成词的词语都扫描出来,速度非常快,但是不能解决歧义,存在冗余;
  3. 搜索引擎模式cut_for_search(s),在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

案例展示如下:

  1. import jieba
  2. with open("wordCloudData.txt", "r", encoding='utf-8') as f: # 读取我们的待处理文本
  3. txt = f.read()
  4. f.close()
  5. remove_data = [",", "。", '\n', '\xa0', ' '] # 无效数据
  6. # '\xa0' 就是 HTML里的&nbsp;
  7. # 去除无效数据
  8. for r_data in remove_data:
  9. txt = txt.replace(r_data, "")
  10. words = jieba.lcut(txt) # 使用精确分词模式进行分词后保存为word列表
  11. with open("wordCloud_Save.txt", "w", encoding='utf-8') as f:
  12. for word in words:
  13. f.write(word+' ')
  14. print("File save successfully")
  15. # UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 111: illegal multibyte sequence
  16. # 如果出现上述报错:encoding='utf-8' 没加的缘故

运行成功以后,我们就可以在当前目录下生成wordCloud_Save.txt文件

产生词云图片

wordcloud类的常用方法:

  • generate(text) :由text文本生成词云
  • to_file(filename) :将词云图保存为名为filename的文件

我们要准备纯底色的图作为词云的背景形状,可以用美图秀秀进行扣图,我就找了马的图片进行扣图,放置到白底图层中(PNG或JPG都可以),效果如下:
唤醒手腕Python网络爬虫学习笔记 - 图20
生成词云需要调用字体库,找到计算机本地的字库,选择合适某个字库,复制一份,放到当前目录下。路径:此电脑 > C: > Windows > Fonts
唤醒手腕Python网络爬虫学习笔记 - 图21
我们当前目录下的文件如下所示:
唤醒手腕Python网络爬虫学习笔记 - 图22

  1. from wordcloud import WordCloud
  2. import matplotlib.pyplot as plt
  3. import numpy
  4. from PIL import Image
  5. mask = numpy.array(Image.open("horseBackImg.jpg"))
  6. # 读取词云形状背景图
  7. with open("wordCloud_Save.txt", "r", encoding='utf-8') as f:
  8. txt = f.read()
  9. f.close()
  10. #读取txt(所要生成词云的数据)
  11. word = WordCloud(background_color="white", width=1200, height=1200, font_path='STXINGKA.TTF', mask=mask,).generate(txt)
  12. word.to_file('finalImg.png')
  13. #background_color 生成词云图的背景颜色。red,blue
  14. print("词云图片已保存,名称为finalImg.png")
  15. plt.imshow(word) # 使用plt库显示图片
  16. plt.axis("off") # 关闭坐标轴
  17. plt.show() # 启动展示

完整的代码展示:

  1. from wordcloud import WordCloud
  2. import matplotlib.pyplot as plt
  3. import jieba
  4. import numpy
  5. from PIL import Image
  6. with open("wordCloudData.txt", "r", encoding='utf-8') as f: # 读取我们的待处理文本
  7. txt = f.read()
  8. f.close()
  9. remove_data = [",", "。", '\n', '\xa0', ' '] # 无效数据
  10. # 去除无效数据
  11. for r_data in remove_data:
  12. txt = txt.replace(r_data, "")
  13. words = jieba.lcut(txt) # 使用精确分词模式进行分词后保存为word列表
  14. with open("wordCloud_Save.txt", "w", encoding='utf-8') as f:
  15. for word in words:
  16. f.write(word + ' ')
  17. f.close()
  18. print("File save successfully")
  19. # UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 111: illegal multibyte sequence
  20. # 如果出现上述报错:encoding='utf-8' 没加的缘故
  21. mask = numpy.array(Image.open("horseBackImg.jpg"))
  22. with open("wordCloud_Save.txt", "r", encoding='utf-8') as f:
  23. txt = f.read()
  24. f.close()
  25. word = WordCloud(background_color="white", width=2000, height=2000, font_path='STXINGKA.TTF', mask=mask,).generate(txt)
  26. word.to_file('finalImg.png')
  27. print("词云图片已保存,名称为finalImg.png")
  28. plt.imshow(word) # 使用plt库显示图片
  29. plt.axis("off")
  30. plt.show()

点击运行,展示效果
唤醒手腕Python网络爬虫学习笔记 - 图23