美文网首页大数据,机器学习,人工智能
用python爬取 20w 表情包之后,感叹我族人是多么强大!

用python爬取 20w 表情包之后,感叹我族人是多么强大!

作者: A遇上方知友 | 来源:发表于2019-05-28 14:21 被阅读3次

    是这样的

    有一次想要斗图

    配图

    就在网上搜索表情包

    然后发现了一个表情巨多的网站

    不小心动起了邪念

    产生了兴趣

    image

    那就

    把它们存下来吧

    用 requests 请求了一下

    发现这个网站没有做反爬

    image

    发现这里有 4k+ 的页面

    image

    简单的切换一下页面

    可以发现

    第一页的链接是这样的

    https://fabiaoqing.com/biaoqi...

    所以以此类推

    构建一下所有url

    <pre class="hljs ini" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 0.75em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">_url = 'https://fabiaoqing.com/biaoqing/lists/page/{page}.html'</pre>

    这样我们就可以得到所有表情包的链接了

    我们来看一下页面里面的信息

    image

    在这里

    我们只需要图片的地址和图片的名称即可

    所以我们只要获取到每个页面的

    所有 img 标签就可以了

    可以使用 BeautifulSoup 根据类名获取

    <pre class="hljs ini" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 0.75em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">response = requests.get(url)</pre>

    拿到了页面里面的所有 img

    那么就可以获取每个图片的地址和名称

    从而下载到我们想要的位置

    <pre class="hljs groovy" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 0.75em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">for img in img_list:</pre>

    至此

    几行代码就搞定了

    先来测试一下

    下载一个页面的图片

    image

    可以发现

    每张图片都获取到了

    效果还行

    不过

    要下载那么多张表情包的话

    这样写的代码有点慢了

    image

    还是开启多线程吧

    对于这种 IO 操作

    还是能加快不少下载时间的

    <pre class="hljs ini" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 0.75em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">queue = Queue()</pre>

    在这里创建了 DownloadBiaoqingbao 这个线程类

    然后创建 10 个线程

    把 url 添加到队列中

    来运行一下

    image

    这时候文件夹就写入表情包啦

    image

    经过一段时间

    小帅b的文件夹就存满了各种表情包了哈哈哈

    谁敢跟我斗图

    我就砸死他

    image

    不过呢

    有个问题

    文件夹里面的图片太多了

    需要检索一下才行

    比如我们要找到关于

    小老弟

    的表情包

    那么我们可以使用

    glob

    <pre class="prettyprint hljs vim" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">import glob
    for name in glob.glob('/home/wistbean/biaoqingbao/小老弟.*'):
    print(name)</pre>

    如果有想要学习Python或者正在学习Python中的小伙伴,需要学习资料的话,可以到我的微信公众号:Python学习知识圈,后台回复:“01”,即可拿Python学习资料

    通过 * 这个符号进行模糊匹配

    运行一下可以得到所有含有“小老弟”的表情包

    image

    到这里

    已经有了大量的表情包

    也可以通过关键词检索到表情包了

    那么如何进一步用到微信来呢

    嘿嘿,我得意的笑

    image

    开下脑洞

    我们使用微信的接口和 python 对接一下

    比如

    我发送给我的微信说

    我要关于沙雕的表情包,发 6 张来

    这个时候

    python接收到指令

    然后就去检索表情包

    发送回我的微信

    可以使用 itchat 这个模块

    使用网页版微信的方式登录

    <pre class="hljs less" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 0.75em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">itchat.auto_login(hotReload=True)
    itchat.run()</pre>

    运行这段代码可以得到二维码

    扫一下就可以登录进去操作微信了

    接着就可以根据小帅b发送过来的关键词

    进行文件搜索

    <pre class="prettyprint hljs python" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">imgs = []

    def searchImage(text):
    print('收到关键词: ', text)
    for name in glob.glob('/home/wistbean/biaoqingbao/'+text+'.jpg'):
    imgs.append(name)

    然后就可以在回复微信的时候发送图片给自己了

    在这里就给自己发前 6 张图片吧

    <pre class="prettyprint hljs python" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">@itchat.msg_register([PICTURE, TEXT])
    def text_reply(msg):
    searchImage(msg.text)
    for img in imgs[:6]:
    msg.user.send_image(img)
    time.sleep(0.3)
    print('开始发送表情:', img)
    imgs.clear()</pre>

    但这里有个问题

    就是 itchat 在发送图片的时候

    中文名的文件发了没有反应

    后来小帅b发现是 requests 库的问题

    修改它的 fields.py

    <pre class="prettyprint hljs cs" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">value = email.utils.encode_rfc2231(value, 'utf-8')
    # value = '%s*=%s' % (name, value)
    value = '%s="%s"' % (name, value.encode('utf-8'))</pre>

    也就是将

    value = '%s*=%s' % (name, value)

    改成

    value = '%s="%s"' % (name, value.encode('utf-8'))

    ok

    搞定

    image

    ok

    以上

    当然还可以优化一下

    比如每次加载更多同类型的表情包

    将表情包发送给特定的人等等

    自己去玩吧

    image

    相关文章

      网友评论

        本文标题:用python爬取 20w 表情包之后,感叹我族人是多么强大!

        本文链接:https://www.haomeiwen.com/subject/ecqdtctx.html