基于360搜图爬取图片

利用360搜图爬取图片

​ 最近闲得无聊,搞了个基于360搜图的图片爬取。用得都是比较基础的知识,所以这里也分享一下代码。本人也不是什么大佬。代码看看就行。**完整的代码在文章最后面。**下面我就简单介绍一下我爬取的过程。

1.第一步

首先我们要知道360关键字是用什么键来对应的,我记得360是q对应关键字,百度的是wd对应关键字。

如下360连接https://image.so.com/i?q=%E9%A3%9E%E6%9C%BA&src=srp,这里的q后面的%E9%A3%9E%E6%9C%BA就是对应的url编码,知道了连接之后,我们就可以打开网页。

打开网页的代码如下:

# 打开url返回没有解码的html
def open_url(url):
    r.Request(url).add_header('User-Agent',
                              'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36')
    respond = r.urlopen(url)
    try:
        if respond.getcode() == 200:
            html = respond.read()
    except Exception as e:
        page = e.partial
        html = page
    return html

注意的是:我这里没有对爬回来的HTML代码进行encode,也就是说这里的html是二进制的。要解码就需要.encode(‘utf-8’)。

2.第二步

第二步就是分析网页结构了。看看图片都藏在哪里,通过浏览器F12,我们可以看到源代码,我找到了图片的地方。

在这里插入图片描述

从这里我们可以找到图片是所在位置,并且我们可以找到图片的下载地址,但问题来了,这个页面是动态的,也就是说图片的获取也是动态的啦,如果我们只是通过定位到图片,在找图片的地址,未免有点笨了。

然后我继续查看网络传送那里和页面代码,然后我在页面那里找到了页面图片初始化的数据。这些数据存在一段js代码里面,并且数据的结构是json。

在这里插入图片描述

这里我写了两函数来获取信息,我没有使用正则表达式,只是单纯的做了个定位。

# 这里只是针对初始化数据(页面前60-100张进行爬取)
def json_FindInitimg(string, imgurl_dict):
    js = json.loads(string)  # 将标签中的信息进行json加载
    for elevent in iter(js):
        if type(js[elevent]) == type([]):
            for lis in js[elevent]:
                for (key, value) in lis.items():
                    if key == 'thumb_bak':
                        imgurl_dict[value] = value.split('/')[-1].split('.')[-1]
    return imgurl_dict
    
 
# 获取初始化的图片(一般是页面前60或100张)
def find_imgurl(html):
    if html == None:
        return
    imgurl_dict = {}
    d = pq(html)  # 用爬回来的网页str进行网页分析
    scr = d('body')('script')('#initData')  # 找到对应的标签
    imgurl_dict = json_FindInitimg(scr.html(), imgurl_dict)
    return imgurl_dict

爬取的图片连接:(这里要的是下载连接,当然也可以要图片原网站地址)

在这里插入图片描述

生成的字典格式,key是地址,val是图片格式

在这里插入图片描述

当然这些是不够的,这些都是页面初始化的数据。我要的是那些动态传送过来的图片,果然我找到了图片数据的请求。

在这里插入图片描述

并且那些需要的参数我也找到了。它放在一个js代码段里面。这里的sid等其他参数,每次打开网页都不同。

在这里插入图片描述

现在就是万事俱备,只欠东风。

首先拿到那些需要的参数

def find_param(html):
    if html == None:
        return
    d = pq(html)  # 用爬回来的网页str进行网页分析
    scr = d('body')('script')('#initParam')  # 找到对应的标签
    param_dict = json.loads(scr.html().replace("'", '"'))           #爬取回来的参数字典
    return param_dict

然后:(形成连接的url)

# 通过参数形成新的url(通过这些参数形成新的url)
def Newurl(param_dict, num=1):
    urllist = []
    sn = 60
    ps = 1
    for i in range(num):
        URLdata = {
            'q': p.unquote(param_dict['query']),
            'pd': 1,
            'pn': 60,
            'correct': p.unquote(param_dict['query']),
            'adstar': param_dict['adstar'],
            'tab': param_dict['tab'],
            'sid': param_dict['sid'],
            'ras': param_dict['ras'],
            'cn': param_dict['cn'],
            'gn': param_dict['gn'],
            'kn': param_dict['kn'],
            'crn': param_dict['crn'],
            'bxn': param_dict['bxn'],
            'cuben': param_dict['cuben'],
            'src': 'srp',
            'sn': sn,
            'ps': ps,
            'pc': 60
        }
        url = 'https://image.so.com/j?' + p.urlencode(URLdata)
        print('生成批道url:   ' + url)
        urllist.append(url)
        sn += 70
        ps += 70
    return urllist
3.第三步

下载图片下载图片就非常简单了,直接打开图片连接,然后把打开的连接中读取二进制数据,然后保存到文件里面,加上对应的文件命和后缀。

在这里插入图片描述

代码在后面。

4.完整代码

我也不多说,放在也是爬来玩玩,直接给代码。能力水平和精力有限,代码可能有点粗糙。如果出现什么BUG还请各位自己修改。最后说一下,代码里面有两个爬取方向,一个是页面是初始化图片,一个是基于参数请求新的图片。

import urllib.request as r
import urllib.parse as p
from pyquery import PyQuery as pq
import json
import os

# 打开url返回没有解码的html
def open_url(url):
    r.Request(url).add_header('User-Agent',
                              'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36')
    respond = r.urlopen(url)
    try:
        if respond.getcode() == 200:
            html = respond.read()
    except Exception as e:
        page = e.partial
        html = page
    return html


# 获取初始化的图片(一般是页面前60或100张)
def find_imgurl(html):
    if html == None:
        return
    imgurl_dict = {}
    d = pq(html)  # 用爬回来的网页str进行网页分析
    scr = d('body')('script')('#initData')  # 找到对应的标签
    imgurl_dict = json_FindInitimg(scr.html(), imgurl_dict)
    return imgurl_dict


# 获取请求参数(获取请求参数)
def find_param(html):
    if html == None:
        return
    d = pq(html)  # 用爬回来的网页str进行网页分析
    scr = d('body')('script')('#initParam')  # 找到对应的标签
    param_dict = json.loads(scr.html().replace("'", '"'))           #爬取回来的参数字典
    return param_dict


# 通过参数形成新的url(通过这些参数形成新的url)
def Newurl(param_dict, num=1):
    urllist = []
    sn = 60
    ps = 1
    for i in range(num):
        URLdata = {
            'q': p.unquote(param_dict['query']),
            'pd': 1,
            'pn': 60,
            'correct': p.unquote(param_dict['query']),
            'adstar': param_dict['adstar'],
            'tab': param_dict['tab'],
            'sid': param_dict['sid'],
            'ras': param_dict['ras'],
            'cn': param_dict['cn'],
            'gn': param_dict['gn'],
            'kn': param_dict['kn'],
            'crn': param_dict['crn'],
            'bxn': param_dict['bxn'],
            'cuben': param_dict['cuben'],
            'src': 'srp',
            'sn': sn,
            'ps': ps,
            'pc': 60
        }
        url = 'https://image.so.com/j?' + p.urlencode(URLdata)
        print('生成批道url:   ' + url)
        urllist.append(url)
        sn += 70
        ps += 70
    return urllist


# 这里只是针对(页面前60-100张进行爬取)
def json_FindInitimg(string, imgurl_dict):
    js = json.loads(string)  # 将标签中的信息进行json加载
    for elevent in iter(js):
        if type(js[elevent]) == type([]):
            for lis in js[elevent]:
                for (key, value) in lis.items():
                    if key == 'thumb_bak':
                        print((key, value))
                        imgurl_dict[value] = value.split('/')[-1].split('.')[-1]
    return imgurl_dict


# 下载
def download(dirpath, imgurl_dict):
    count = 0
    print(imgurl_dict)
    for (imgurl, type) in imgurl_dict.items():
        if type == 'jpg' or type == 'png' or type == 'jpeg':
            print("图片[   %s   ]开始下载......" % imgurl)
            html = open_url(imgurl)
            path = dirpath + str(count) + '.' + type
            print("图片写入路径是:%s" % dirpath + path)
            with open(path, mode='wb') as f:
                f.write(html)
            count += 1
    return count


# 不同的下载方式,下载不同数量的图片
def download_img(url, dirpath, num=None):
    Pcount = 1  # 批道数

    if num == None:
        html = open_url(url).decode('utf-8')
        imgurl_dict = find_imgurl(html)
        os.mkdir(dirpath + str(Pcount))
        download(dirpath+str(Pcount)+'\\', imgurl_dict)
    else:
        html = open_url(url).decode('utf-8')

        for i in Newurl(find_param(html), num=num):
            newhtml = open_url(i).decode('utf-8')
            imgurl_dict = {}
            json_FindInitimg(newhtml, imgurl_dict)
            os.mkdir(dirpath+str(Pcount))        #工具批道数新建文件夹
            download(dirpath+str(Pcount)+'\\', imgurl_dict)          #下载到对应的文件夹
            Pcount +=1


if __name__ == '__main__':
    path = 'F:\\my_img\\'      #根目录(每一批会在根目录建一个新目录)   最后记得加个'\\'结尾
    Qval = input('请输入你要搜索的图片:')
    mod = input('请输入爬取方式:(1:爬取页面前60-100张\t0:爬取指定数量)')
    data = {
        'q': Qval,
        'src': 'srp'
    }
    url = 'https://image.so.com/i?' + p.urlencode(data)
    if mod == '1':
        download_img(url, dirpath=path)
    else:
        num = int(input('请输入爬取批数:(一般60/批)'))
        download_img(url, dirpath=path, num=num)

爬取结果如下:(爬取的一些动漫图片)
在这里插入图片描述

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值