吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2432|回复: 3
收起左侧

[Python 原创] 简单爬取百度图片并转换为灰度照

  [复制链接]
科迈罗 发表于 2020-8-20 22:31
本帖最后由 wushaominkk 于 2020-8-21 14:18 编辑

# 0. 准备
专业的抓包工具我喜欢用wireshark,不过这篇没用多少抓包技巧
编辑器用的是pycharm2020.1.1
python版本是win10子系统自带的3.6
一堆第三方库都是用pycharm装的,很方便


# 1. 抓包百度图片官网https://image.baidu.com/ ,随机在首页搜索一个关键字

批注 2020-08-19 095644.png

然后F12观察,点一下左上角的垃圾桶图标,

Inked批注 2020-08-19 095739_LI.jpg

然后F5刷新一下,经过观察,我们要找的触发源是XHR中的html类型文件

批注 2020-08-19 101308.png

轻轻往下一滑,发现,`pn`参数里面存在规律,步长为30递增

批注 2020-08-19 101351.png

批注 2020-08-19 101422.png

然后将该请求中所有的参数都copy下来,打成一个字典,作为params
** 注意这里的最后一个参数1597926642252,每天都在变**
由于每页30个图片,将30作为迭代步长,做成列表

批注 2020-08-20 215708.png

# 2. 简单爬取以下

批注 2020-08-20 215837.png

由于没加UA也没加代{过}{滤}理,只爬到了一个200的状态值。。。。
再次观察这个请求的response,提取每一张图片的url,此处可考虑用bs4、re,笔者只是简单使用字符串的识别

批注 2020-08-20 203655.png

批注 2020-08-20 213853.png

# 3. 面向对象

先将爬取、下载图片两步分别封装为两个函数,然后使用面向对象的特性,将整个爬虫写成一个类
过程是先有getPages方法获取每一页的图片url,然后返回一个url列表给downloadJpg下载函数逐条下载

批注 2020-08-20 214803.png

批注 2020-08-20 220349.png

# 4. 转换颜色

利用numpy,将图片转换为灰度照片,具体代码如下,没啥好说的,不懂的翻一下官方帮助文档

批注 2020-08-20 215126.png

以上代码已经将转换颜色也封装为一个函数,然后添加到类方法中,转换之后的图片存储在另一个文件夹中,完整类代码如下

[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import requests
import os
import random
from PIL import Image
from bs4 import BeautifulSoup
import numpy

user_agent = ['Mozilla/5.0(Windows;U;WindowsNT6.1;en-us)AppleWebKit/534.50(KHTML,likeGecko)Version/5.1Safari/534.50',
              'Mozilla/5.0(compatible;MSIE9.0;WindowsNT6.1;Trident/5.0',
              'Mozilla/4.0(compatible;MSIE8.0;WindowsNT6.0;Trident/4.0)',
              'Mozilla/5.0(Macintosh;IntelMacOSX10.6;rv:2.0.1)Gecko/20100101Firefox/4.0.1',
              'Mozilla/5.0(Macintosh;IntelMacOSX10_7_0)AppleWebKit/535.11(KHTML,'
              'likeGecko)Chrome/17.0.963.56Safari/535.11',
              'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Maxthon2.0)',
              'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;TencentTraveler4.0)',
              'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;Trident/4.0;SE2.XMetaSr1.0;SE2.XMetaSr1.0;.NETCLR2.0.50727'
              ';SE2.XMetaSr1.0)',
              'Mozilla/4.0(compatible;MSIE7.0;WindowsNT5.1;360SE)',
              'Mozilla/5.0(Macintosh;U;IntelMacOSX10_6_8;en-us)AppleWebKit/534.50(KHTML,'
              'likeGecko)Version/5.1Safari/534.50']


class GetBaiduImg(object):
    kw = {'Host': 'image.baidu.com'}
    urls = list()

    def __init__(self, result, n):
        """
        :param result: 输入百度图片搜索的关键词
        :param n: 输入要爬取的页数
        """
        self.downloadJpg(datalist=self.getPages(result, n))
        self.convertColor('./baidu')

    def getPages(self, keyword, pages):
        try:
            GetBaiduImg.kw['user-agent'] = random.choice(user_agent)
            param = list()
            for i in range(30, pages * 30 + 30, 30):
                param.append({'tn': 'resultjson_com', 'ipn': 'rj',
                              'ct': '201326592', 'is': '', 'fp': 'result', 'queryWord': keyword, 'cl': '2',
                              'lm': '-1', 'ie': 'utf-8', 'oe': 'utf-8', 'adpicid': '', 'st': '-1',
                              'z': '', 'ic': '0', 'hd': '', 'latest': '', 'copyright': '',
                              'word': keyword, 's': '', 'se': '', 'tab': '', 'width': '', 'height': '',
                              'face': '0', 'istype': '2', 'qc': '', 'nc': '1', 'fr': '', 'expermode': '',
                              'force': '', 'pn': i, 'rn': '30', 'gsm': '1e', '1597926642252': ''})
            start_url = 'https://image.baidu.com/search/acjson'
            for i in param:
                res = requests.request(method='get', url=start_url, headers=GetBaiduImg.kw, params=i,
                                       proxies={"http": "175.43.58.44:9999"})
                res.raise_for_status()
                res.encoding = res.apparent_encoding
                response = res.content.decode('utf-8')
                for a in response.split('"'):
                    if "https://ss" and ".jpg" and "bdstatic" in a:
                        GetBaiduImg.urls.append(a)
            return set(GetBaiduImg.urls)
        except requests.RequestException as e:
            print('mistake info==>', str(e))

    def downloadJpg(self, datalist, direct='./baidu'):
        if not os.path.exists(direct):
            os.mkdir(direct)
        x = 1
        for data in datalist:
            if len(data):
                print(f'downloading img {data}')
                try:
                    resp = requests.request(method='get', url=data, proxies={"http": "175.43.58.44:9999"})
                    open(f'{direct}/{x}.jpg', 'wb').write(resp.content)
                    x += 1
                except Exception as exp:
                    print("misktake info==>",str(exp))

    def convertColor(self, direct):
        for i in os.listdir(direct):
            im = numpy.array(Image.open(direct + '/' + f'{i}').convert('L')).astype('float')
            print(f"converting img {i} with ", im.shape, im.dtype)
            depth = 10
            grad = numpy.gradient(im)
            grad_x, grad_y = grad
            grad_x = grad_x * depth / 100
            grad_y = grad_y * depth / 100
            A = numpy.sqrt(grad_x ** 2 + grad_y ** 2 + 1)
            uni_x = grad_x / A
            uni_y = grad_y / A
            uni_z = 1 / A
            vec_el = numpy.pi / 2.2
            vec_az = numpy.pi / 4
            dx = numpy.cos(vec_el) * numpy.cos(vec_az)
            dy = numpy.cos(vec_el) * numpy.sin(vec_az)
            dz = numpy.sin(vec_el)
            b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)
            a = b.clip(0, 255)
            im = Image.fromarray(a.astype('uint8'))
            im.save(direct + '/' + f'[灰度照]{i}')


if __name__ == "__main__":
    baiduimg = GetBaiduImg(result="郁金香", n=1)

最后贴上运行结果

批注 2020-08-20 220810.png

批注 2020-08-20 220940.png

批注 2020-08-20 221012.png

第一篇文章,如有需改进的地方还望指出,下篇会考虑在proxies上下功夫,以及调用mysql等等


免费评分

参与人数 3吾爱币 +9 热心值 +2 收起 理由
wushaominkk + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
che_shen + 1 用心讨论,共获提升!
xyc171918040 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

grape722 发表于 2020-8-21 21:33
本帖最后由 grape722 于 2020-8-21 21:37 编辑

请教一下楼主,为什么爬下来的全是分辨率低的小图?实际搜索的结果很多大图,但是爬取出来很少有大图。
如图:280多张图片,分辨率不高,好像都是搜索结果里预载入的图片,不是实际大小的。
360截图17290508323481.png
王小帅先生 发表于 2020-8-22 10:04
 楼主| 科迈罗 发表于 2020-8-25 07:55
grape722 发表于 2020-8-21 21:33
请教一下楼主,为什么爬下来的全是分辨率低的小图?实际搜索的结果很多大图,但是爬取出来很少有大图。
如 ...

发起的请求中图片的顺序和看到的顺序肯定有区别,你可以把图片按大小排序之后再试试
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 01:59

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表