专栏首页bigsai写文没高质量配图?教你python爬虫绕过限制一键搜索下载图虫创意图片!

写文没高质量配图?教你python爬虫绕过限制一键搜索下载图虫创意图片!

在我们写文章(博客、公众号、自媒体)的时候,常常觉得自己的文章有些老土,这很大程度是因为配图没有选好。本文将和大家分享一个实用爬虫案例!

笔者也是遇到相同的情况,顺便解决其中一个案例,给大家一些技术上的参考和借鉴!

并且,我们搜图片如果去百度,会遇到两种情况:非高清或者带水印。这都是我们所忌讳的东西。笔者此次通过图虫创意抓起高清小图,虽然不是大图,但是在火热的移动端阅读上是足够的!

分析

废话说完了,我们开始分析怎么样才能获取这样的图片呢。

理想状态

我们的理想状态就是一个网页,我们的目标网页,把图片<img src="xxxxxx">直接放到html中。我们的爬虫可以直接解析。这种情况,就像你写的博客,个人网站的图片一样,简单嵌入。

或者就是通过后台ajax传输图片地址引用。我们不清楚是否这样!

实际分析

但事实这种肯定会被理想破灭,因为不可能!他以图片为核心业务,要你注册,购买等等,怎么可能就这么容易的嵌入进入被你找到。

  • 那它到底如何实现呢?我们分析一下!

首先打开网页,检查图片,发现它的网页图片来源不唯一。有两个主要域名icewel,并且后面的编号还不唯一,但是可以尝试发现相同域名不同后缀的图片地址结果相同!(例如icweiliimg9icweiliimg/效果相同)。

我们发现原来这个搜索url会变化,但是这个查看网页源代码发现并没有我们想要的图片地址。那么我们肯定知道它要么从ajax渲染,或者就藏在js中进行混淆或者加密。我们发现这个xhr中并没有想要的数据,并且他其实藏在js中。其实这个可以猜想到的,因为它的url既然跟着变化那么返回的数据肯定是有区别的。

那么分析就到这里,剩下就是python爬虫的模拟和解析了。

爬虫实现

前面说到已经知道它的数据源,我们用python编写爬虫需要进行模拟。经过测试发现它需要进行一些验证,其中包过cookiewluuid字段(只验证存在,不验证正确性)。

那么我们编写一段代码就能拿到网页html。但是问题来了。数据藏在js里面啊!!!

我们只能用正则进行套了! 对于这个js,我们通过js=soup.select('script') js=js[4]即可获取。

对于有用数据,只能正则截取。

 pattern = re.compile(r'window.hits = (\[)(.*)(\])')
 va = pattern.search(str(js)).group(2)#解析js内容

但是这个类似json的串用,拼接我们无法直接使用spilt分组分开,但是我们可以从}全部替换成},,那么就三个,,,我们就可以分割而不影响其他json串内,;split之后每组都满足json串格式,直接转成json取值即可!

那么剩下拿到url直接构造url然后下载图片即可!

其他注意

图片下载:

  • 下载图片有很多图片无名称或者名字相同,避免这个不下载要进行编号
  • 两个url域名需要尝试下载其中一个成功即完成下载!

爬虫方面

  • 全程不需要登录,下载为高清小图。后续可以考虑研究登录后的大图分享给大家!

其他

  • 創建图片路径要考虑路径是否存在!

代码与总结

通过上述分析:编写爬虫:

import  requests
from  urllib import  parse
from bs4 import BeautifulSoup
import re
import json
header = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
    'Cookie': 'wluuid=66;  ',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
    'Accept-encoding': 'gzip, deflate, br',
    'Accept-language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'max-age=0',
    'connection': 'keep-alive'
    , 'Host': 'stock.tuchong.com',
    'Upgrade-Insecure-Requests': '1'
    }
def mkdir(path):
    import os# 引入模块
    path = path.strip()# 去除首位空格
    path = path.rstrip("\\") # 去除尾部 \ 符号
    isExists = os.path.exists(path)  # 判断路径是否存在  # 存在     True # 不存在   False
    if not isExists:  # 判断结果
        os.makedirs(path)# 如果不存在则创建目录 # 创建目录操作函数
        return True#print (path + ' 创建成功')
    else:
        # 如果目录存在则不创建,并提示目录已存在
        #print(path + ' 目录已存在')
         return False
def downloadimage(imageid,imgname):
    url = 'https://weiliicimg9.pstatp.com/weili/ms/'+str(imageid)+'.webp'
    url2 = 'https://icweiliimg9.pstatp.com/weili/ms/'+str(imageid)+'.webp'
    b=False
    r = requests.get(url)
    print(r.status_code)
    if(r.status_code!=200):
        r=requests.get(url2)
    with open(imgname+'.jpg', 'wb') as f:
        f.write(r.content)
        print(imgname+" 下载成功")
def getText(text):
    texturl = parse.quote(text)
    url="https://stock.tuchong.com/search?term="+texturl+"&use=0"
    req=requests.get(url,headers=header)
    soup=BeautifulSoup(req.text,'lxml')
    js=soup.select('script')
    js=js[4]
    print(js)
    pattern = re.compile(r'window.hits = (\[)(.*)(\])')
    va = pattern.search(str(js)).group(2)#解析js内容
    print(va)
    va = va.replace('{', '{').replace('}', '},,')
    print(va)
    va = va.split(',,,')
    print(va)
    index = 1
    for data in va:
        try:
             dict = json.loads(data)
             print(dict)
             imgname='img/'+text+'/'+dict['title']+str(index)
             index+=1
             mkdir('img/'+text)
             imgid=dict['imageId']
             downloadimage(imgid,imgname)
        except Exception as e:
            print(e)
if __name__ == '__main__':
    getText(text=input('输入关键词:'))

测试结果:

打开文件夹:

发现nice!你只需要输入关键词即可实现自动下载,虽然是小图,但是效果不错!

本文分享自微信公众号 - bigsai(bigsai)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [PHP] 看博客学习插入排序

    陶士涵
  • [Laravel] Laravel的基本数据库操作部分

    使用DB类的静态方法select来查询数据库,DB::select(),参数:sql语句,参数值数组

    陶士涵
  • [javaSE] 看知乎学习反射

    简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

    陶士涵
  • 可能是东半球最好的 Curl 学习指南,强烈建议收藏!

    curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。

    iMike
  • [PHP] 看博客学习观察者模式

    具体应用场景是,当subject的某个动作需要引发一系列不同对象的动作(比如你是一个班长要去通知班里的某些人),与其一个一个的手动调用触发的方法(私下里一个一个...

    陶士涵
  • [Redis] redis在centos下安装测试

    wget http://download.redis.io/releases/redis-3.0.0.tar.gz

    陶士涵
  • [PHP] B2B2C商品模块数据库设计

    /**************2016年4月25日 更新********************************************/

    陶士涵
  • [PHP] 排序和查找算法

    冒泡排序的原理可以顾名思义:把每个数据看成一个气泡,按初始顺序自底向上依次对两两气泡进行比较,对上重下轻的气泡交换顺序(这里用气泡轻、重表示数据大、小),保证轻...

    陶士涵
  • [javaSE] 看博客学习多线程的创建方式和优劣比较和PHP多线程

    Runnable是一个接口,定义一个类MyRunnable实现Runnable接口,实现run()方法,

    陶士涵
  • [MongoDB] mongodb与php

    下载地址https://s3.amazonaws.com/drivers.mongodb.org/php/index.html

    陶士涵

扫码关注云+社区

领取腾讯云代金券