青梅梦呓

和世界交手的这许多年,你是否光彩依旧,兴致盎然

0%

Python爬取微信公众号上的图片

最近斗图老输,完全不符合我表情包之王,国家殿堂级斗图高手的身份,一直想着怎么给我的表情包扩充一下新的血液;在B站也刷到半佛仙人的视频,发现他的表情包是多而沙雕,也刷到了桂大佬做的怎么下载,就顺着写了一下。现在的版本暂时只下载一篇文章中的,后续版本下载公众号中全部文章的图片。

我的Mac OS系统是10.15.4版本的,使用PyCharm开发,开始写的时候python版本是3.7的,后续升级成为了3.8.2

安装使用3.8.2版本的python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
brew update && brew upgrade
# 安装pyenv 我之前没有,已经安装的可以不用
brew install pyenv
# 我使用 oh-my-zsh SHELL
echo 'export PATH="$(pyenv root)/shims:$PATH"' >> ~/.zshrc
source ~/.zshrc
# 目前最新的python3.8.2 选择适合的
pyenv install --list | grep 3.8
# 安装3.8.2
pyenv install 3.8.2
# 查看目前的python
pyenv versions
pyenv local 3.8.2
# 设置全局 pyenv --help可以查看
pyenv global 3.8.2
# type查看
type -a python
# 重新打开终端
python -V
# 顺手升级pip
pip install --upgrade pip

PyCharm 使用pytho3.8.2

在项目的右下角可以看到PyCharm当前使用的Python解释器版本,默认是跟谁系统的3.7.2(brew install python)。 通过以下操作可以将其更换为3.8.2

Preferences(Command + ,) -> Project -> Python Interpreter -> 选择Python3.8.2。 如下图所示。
PyCharm解释器配置

爬取页面图片的url

搜狗微信可以直接查看微信的连接,直接用搜狗微信公众号的链接即可,使用requests即可查看到, 查看页面的元素就能看到图片连接都在data-src里面,正则匹配一下就可以

需要安装的库

1
pip install requests
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
def get_urls(url):
try:
html = requests.get(url, timeout=30).text
except requests.exceptions.SSLError:
html = requests.get(url, verify=False, timeout=30).text
except TimeoutError:
print('请求超时')
except Exception:
print('获取图片链接失败')
src = re.compile(r'data-src="(.*?)"')
urls = re.findall(src, html)
if urls is not None:
url_list = []
for url in urls:
url_list.append(url)
return url_list


# main 函数
if __name__ == '__main__'
# 这链接经常会过期,自己去https://weixin.sogou.com/ 搜索可用的链接
# 我使用的文章是 《体育考试作弊会毁了你》
sample = "https://mp.weixin.qq.com/s?src=11&timestamp=1588487130&ver=2315&signature=EbcpQeUVIa3ICzS4H7mTb5mt*o2SrYuEC6Ff0Pr7o7wtVG-OHb-IiSek5Wt6cUFR-X8zwrV5Nri5aoyVLH0ys3kLPOnTfks3ni0RhtPdKHios6B9XTkHhuyOKzNXShF-&new=1"
img_urls = get_urls(sample)
print(img_urls)

一开始不知道为啥我一导入requests包运行程序就会异常退出,纠结了半天才找到问题
因为我的mac的/usr/local/lib 里面没有libssl.dylib 和 libcrypto.dylib这两个文件
旧版本的openssl也可能会有相同问题。 如下操作即可。

1
2
3
4
5
6
7
8
9
cd /usr/local/Cellar/openssl@1.1/1.1.1g/lib
sudo cp libssl.1.1.dylib libcrypto.1.1.dylib /usr/local/lib/
cd /usr/local/lib
# 如果有旧的最好备份一下 mv
mv libssl.dylib libssl_bak.dylib
mv libcrypto.dylib libcrypto_bak.dylib
# 建立软链
sudo ln -s libssl.1.1.dylib libssl.dylib
sudo ln -s libcrypto.1.1.dylib libcrypto.dylib

运行一下就能看到我们已经把这个文章中的图片连接已经全部得到了。

下载图片

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
# 创建保存图片的文件夹
def mkdir(base_path):
isExists = os.path.exists(base_path)
if not isExists:
print('创建目录')
os.makedirs(base_path) # 创建目录
os.chdir(base_path) # 切换到创建的文件夹
return True
else:
print('目录已存在,即将保存!')
return False


# 下载图片并写入到指定的文件夹中
def download(base_path, image_urls):
for url in image_urls:
filename = base_path + url.split('/')[-2] + '.' + url.split('=')[-1]
try:
with open(filename, 'wb+') as f:
try:
f.write(requests.get(url, timeout=30).content)
print('成功下载图片:', filename)
except requests.exceptions.SSLError:
f.write(requests.get(url, verify=False, timeout=30).content)
print('成功下载图片:', filename)
except FileNotFoundError:
print('下载失败!!没有找到对应图片目前,请检查路径:', filename)
pass
except TimeoutError:
print('下载超时:', filename)
pass
except Exception as e:
print('非正常图片,直接忽略:', filename, e)
pass



# main函数
if __name__ == '__main__':
sample = "https://mp.weixin.qq.com/s?src=11&timestamp=1588487130&ver=2315&signature=EbcpQeUVIa3ICzS4H7mTb5mt*o2SrYuEC6Ff0Pr7o7wtVG-OHb-IiSek5Wt6cUFR-X8zwrV5Nri5aoyVLH0ys3kLPOnTfks3ni0RhtPdKHios6B9XTkHhuyOKzNXShF-&new=1"
img_urls = get_urls(sample)
base_path = r'./weichat_pics/'
try:
mkdir(base_path)
except Exception as e:
print("建立文件异常", e)
print("保存图片文件夹正常")
download(base_path, img_urls)

再次运行代码就能看到,已经将这篇文章中所有的图片均已经下载到指定的文件夹中。

使用百度的OCR重命名文件

创建百度文字识别应用

百度账号应该都有,直接到百度AI只能开放平台,登录后直接进入到控制台,点击文字识别。创建应用即可。可以在下面看到调用次数和API类型,可惜就是给的免费QPS低了点。有了应用之后直接使用百度提供的SDK python-aip。

1
pip install baidu-aip

使用OCR识别图片中的文字

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
59
60
61
62
63
64
65
def baiduOCR(picfile):
"""利用百度api识别文本,并保存提取的文字
把下面的ID KEY 和SK替换成自己的就可以了
"""

APP_ID = 'xxxxxx'
API_KEY = 'xxxxxx'
SECRECT_KEY = 'xxxxxxxx'
client = AipOcr(APP_ID, API_KEY, SECRECT_KEY)
i = open(picfile, 'rb')
img = i.read()
try:
message = client.basicGeneral(img)['words_result'] # 通用文字识别
value = []
for j in message:
value.append(j['words'])
t = ''.join(value)
title = t.replace('/', '').replace('\\', '').replace(':', '').replace('*', '').replace('?', '').replace('<', '') \
.replace('>', '').replace('|', '').replace('.', '')
# .strip('/').strip('\\').strip(':').strip('*').strip('?').strip('<').strip('>').strip('|').strip('.')
timestamp = int(time.time())
if title == "" or title == None:
title = timestamp
return title
i.close()
return title
except Exception as e:
print(e)
print('此图片类型无法识别')



# 修改下download函数,在下载完一张图片后就试着重命名下
def download(base_path, image_urls):
for url in image_urls:
filename = base_path + url.split('/')[-2] + '.' + url.split('=')[-1]
try:
with open(filename, 'wb+') as f:
try:
f.write(requests.get(url, timeout=30).content)
print('成功下载图片:', filename)
except requests.exceptions.SSLError:
f.write(requests.get(url, verify=False, timeout=30).content)
print('成功下载图片:', filename)
except FileNotFoundError:
print('下载失败!!没有找到对应图片目前,请检查路径:', filename)
pass
except TimeoutError:
print('下载超时:', filename)
pass
except Exception as e:
print('非正常图片,直接忽略:', filename, e)
pass
try:
title = baiduOCR(filename)
timestamp = int(time.time())
pic_type = url.split('=')[-1]
if pic_type == 'gif':
new_name = base_path + str(timestamp) + '.' + pic_type
else:
new_name = base_path + str(title) + '.' + pic_type
os.rename(filename, new_name)
print('文件重命名成功% s' % (new_name))
except Exception as e:
print('重命名失败!忽略', e)

Ps: pip instll aip 和pip install baidu-aip下载是两个包,前者需要暂时卸载了

再次运行程序,基本就能看到已经有些字迹清晰完整的图片已经成功重新命名。

完整程序代码

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# -*- coding: UTF-8 -*-

import os
import re
import time
import requests

from aip import AipOcr


def baiduOCR(picfile):
"""利用百度api识别文本,并保存提取的文字
把下面的ID KEY 和SK替换成自己的就可以了
"""

APP_ID = 'xxxxxxxxx'
API_KEY = 'xxxxxxxxx'
SECRECT_KEY = 'xxxxxxxxx'
client = AipOcr(APP_ID, API_KEY, SECRECT_KEY)
i = open(picfile, 'rb')
img = i.read()
try:
message = client.basicGeneral(img)['words_result'] # 通用文字识别
value = []
for j in message:
value.append(j['words'])
t = ''.join(value)
title = t.replace('/', '').replace('\\', '').replace(':', '').replace('*', '').replace('?', '').replace('<', '') \
.replace('>', '').replace('|', '').replace('.', '')
# .strip('/').strip('\\').strip(':').strip('*').strip('?').strip('<').strip('>').strip('|').strip('.')
timestamp = int(time.time())
if title == "" or title == None:
title = timestamp
return title
i.close()
return title
except Exception as e:
print(e)
print('此图片类型无法识别')


def get_urls(url):
try:
html = requests.get(url, timeout=30).text
except requests.exceptions.SSLError:
html = requests.get(url, verify=False, timeout=30).text
except TimeoutError:
print('请求超时')
except Exception:
print('获取图片链接失败')
src = re.compile(r'data-src="(.*?)"')
urls = re.findall(src, html)
if urls is not None:
url_list = []
for url in urls:
url_list.append(url)
return url_list


def mkdir(base_path):
isExists = os.path.exists(base_path)
if not isExists:
print('创建目录')
os.makedirs(base_path) # 创建目录
os.chdir(base_path) # 切换到创建的文件夹
return True
else:
print('目录已存在,即将保存!')
return False


def download(base_path, image_urls):
for url in image_urls:
filename = base_path + url.split('/')[-2] + '.' + url.split('=')[-1]
try:
with open(filename, 'wb+') as f:
try:
f.write(requests.get(url, timeout=30).content)
print('成功下载图片:', filename)
except requests.exceptions.SSLError:
f.write(requests.get(url, verify=False, timeout=30).content)
print('成功下载图片:', filename)
except FileNotFoundError:
print('下载失败!!没有找到对应图片目前,请检查路径:', filename)
pass
except TimeoutError:
print('下载超时:', filename)
pass
except Exception as e:
print('非正常图片,直接忽略:', filename, e)
pass
try:
title = baiduOCR(filename)
timestamp = int(time.time())
pic_type = url.split('=')[-1]
if pic_type == 'gif':
new_name = base_path + str(timestamp) + '.' + pic_type
else:
new_name = base_path + str(title) + '.' + pic_type
os.rename(filename, new_name)
print('文件重命名成功% s' % (new_name))
except Exception as e:
print('重命名失败!忽略', e)


if __name__ == '__main__':
sample = "https://mp.weixin.qq.com/s?src=11&timestamp=1588487130&ver=2315&signature=EbcpQeUVIa3ICzS4H7mTb5mt*o2SrYuEC6Ff0Pr7o7wtVG-OHb-IiSek5Wt6cUFR-X8zwrV5Nri5aoyVLH0ys3kLPOnTfks3ni0RhtPdKHios6B9XTkHhuyOKzNXShF-&new=1"
img_urls = get_urls(sample)
base_path = r'./weichat_pics/'
try:
mkdir(base_path)
except Exception as e:
print("建立文件异常", e)
print("保存图片文件夹正常")
download(base_path, img_urls)