使用百度搜索指定类型和数量爬取图片(一百行爬虫小程序)

前段时间学习爬虫的时候,看了b站一个视频,感觉受益良多,其中的百度图片爬虫让我觉得很nice,今天想做一个神经网络的性别分类,需要用到男人和女人的图片,我就又想起了它,顺手整理了一下,分享出来。话不多说,先上效果图。

这里是全部代码

import requests
import os
import json
from threading import Thread
import numpy as np

# import threading
class baidu_photo():#获取图片数据
    urls = []#装载返回的图片数据,json数据
    def getpages(self,kw,num):
        '''

        :param kw:搜索关键字
        :param num: 爬取图片的数目,num*30
        :return: 列表
        '''
        url='https://image.baidu.com/search/acjson'#百度图片搜索地址
        #请求头,将爬虫伪装成谷歌浏览器,如果不想写,有个包可以自动产生请求头(忘了,,,)
        headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'
        }
        params=[]
        for i in num:#num为请求的数目,是一个列表,一次请求三十张图片
        #下面的一堆参数,在网址里面,按F12,调出开发者选项,在network里面,选择XHR,百度的图片刷新是ajax,所以只需要看xhr即可,点击刷新,就可以找到
            params.append({
                'tn': 'resultjson_com',
                'ipn': 'rj',
                'ct': '201326592',
                'is': '',
                'fp': 'result',
                'queryWord': kw,#请求的关键字
                'cl': '2',
                'lm': '-1',
                'ie': 'utf-8',
                'oe': 'utf-8',
                'adpicid': '',
                'st': '-1',
                'z': '',
                'ic': '0',
                'hd': '',
                'latest': '',
                'copyright': '',
                'word': kw,
                's': '',
                'se': '',
                'tab': '',
                'width': '',
                'height': '',
                'face': '0',
                'istype': '2',
                'qc': '',
                'nc': ' 1',
                'fr': '',
                'expermode': '',
                'force': '',
                'pn': i,#更换此参数,将返回不同的页面
                'rn': '30',
                'gsm': '3c',
                '1590113448337': '',
            })

        p_thread=[]
        for i in params:#迭代上面获取的页面
            # res=requests.get(url,i)
            # res=json.loads(res.text,strict=False)
            # urls.append(res['data'])
            p=Thread(target=self.Thead,args=(url,i,headers))#使用线程,每三十张一个线程爬取
            p.start()
            p_thread.append(p)#将线程加入线程列表

        [i.join() for i in p_thread]#所有线程列表加入完成后,开始阻塞运行线程,join为阻塞模式,如果不使用,则主程序结束线程结束,使用则可以让所以线程爬虫爬取完毕
        #因为线程是依赖于主进程的,线程与进程一同运行,爬虫的速度肯定慢于主进程(不负责任的说,,,应该是这个样子)
        print('获取图片地址成功')
        return self.urls

    def Thead(self,url,i,headers):#线程开始
        res = requests.get(url, i,headers=headers)#线程发送get请求,获取返回值(json数据,如果是个html页面就说明上面那个params出错了)
        res = json.loads(res.text, strict=False)#json解析返回值,变成字典类型{'key','value'}是字典"{'key','value'}"是json,通俗的说json是一个字典样式的字符串
        self.urls.append(res['data'])#将json里面包含图片url的数据存入全局列表urls
        # pass

    def get_images(self,kw,img_urls,dir):#下载图片
        '''

        :param kw:请求关键字,同时作为图片存储的文件夹名称
        :param img_urls:图片地址
        :param dir:保存的目录
        :return:none
        '''
        # print(img_urls)
        x=0#图片的初始名字
        dir=dir+'/'+kw#创建一个文件夹,名字为搜索的关键字
        if not os.path.exists(dir):#判断该文件夹是否存在
            print('创建目录!')
            os.makedirs(dir)#不存在创建目录,值得一提的是,makedir只能创建当前路劲下一层文件夹,如果多一层就会报错,使用makedirs
        for data in img_urls:#获取每一次请求的数据
            for i in data:#获取一次请求里面所有的数据
                if i.get('thumbURL')!=None:#判断键thumbURL是否为空/存在
                    res=requests.get(i.get('thumbURL'))#得到了图片的url,发起get请求
                    print(f'正在下载{i.get("thumbURL")}')
                    open(f'{dir}/{x}.jpg','ab').write(res.content)#以追加的方式发开一个图片文件,名字为x.jpg,保存的为二进制文件,使用ab,res.content为二进制数据
                    x+=1
    def start(self,num):#开始爬取

        keyWord = input('请输入下载内容:')#输入搜索关键字
        # num = 1
        p_list = self.getpages(keyWord, num=num)#调用函数
        self.get_images(keyWord, p_list, './baidu_photo')
if __name__ == '__main__':

    baidu=baidu_photo()
    # num=5
    num = int(input('请输入下载数目(30*):'))
    number=np.random.randint(1,20,num)*30#因为是使用的百度搜图,为了防止每次搜出来的都一样,选择了随机数,randint,从1到20生成num个数,返回一个列表
    print(number)
    # num=3
    baidu.start(num=number)#开始爬取

这个东西我还弄了一个qt页面,但是,,老是出问题,我嗯是裂开了,如果有兴趣的可以试试,我也一并放这里。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'baidu.ui'
#
# Created by: PyQt5 UI code generator 5.14.1
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_baidu(object):
    def setupUi(self, baidu):
        baidu.setObjectName("baidu")
        baidu.resize(520, 383)
        baidu.setStyleSheet("background-color:rgb(146,178,173);")
        self.centralwidget = QtWidgets.QWidget(baidu)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(90, 10, 251, 61))
        self.label.setStyleSheet("font-size:40px;\n"
"color:white;")
        self.label.setObjectName("label")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(160, 130, 181, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(80, 130, 71, 31))
        self.label_2.setObjectName("label_2")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(260, 180, 81, 28))
        self.pushButton.setStyleSheet("border:1px solid black;\n"
"border-radius:5px;\n"
"background-color:black;\n"
"color:white;\n"
"font-size:20px;")
        self.pushButton.setObjectName("pushButton")
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(380, 10, 121, 301))
        self.textEdit.setObjectName("textEdit")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(400, 0, 72, 15))
        self.label_3.setObjectName("label_3")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_2.setGeometry(QtCore.QRect(160, 180, 91, 31))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(80, 180, 71, 31))
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(0, 304, 61, 21))
        self.label_5.setStyleSheet("border:1px solid blue;")
        self.label_5.setObjectName("label_5")
        baidu.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(baidu)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 520, 26))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        baidu.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(baidu)
        self.statusbar.setObjectName("statusbar")
        baidu.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menu.menuAction())

        self.retranslateUi(baidu)
        self.pushButton.clicked.connect(self.baidu_spader)
        QtCore.QMetaObject.connectSlotsByName(baidu)

    def retranslateUi(self, baidu):
        _translate = QtCore.QCoreApplication.translate
        baidu.setWindowTitle(_translate("baidu", "MainWindow"))
        self.label.setText(_translate("baidu", "批量图片下载"))
        self.label_2.setText(_translate("baidu", "图片类型:"))
        self.pushButton.setText(_translate("baidu", "下载"))
        self.label_3.setText(_translate("baidu", "下载日志"))
        self.lineEdit_2.setPlaceholderText(_translate("baidu", "输入数*30张"))
        self.label_4.setText(_translate("baidu", "图片数量:"))
        self.label_5.setText(_translate("baidu", "Spider"))
        self.menu.setTitle(_translate("baidu", "百度图片"))

这是qt设计出来直接生成的,,额,我好像忘记拉槽函数了,,,卧槽,打着字打着我似乎突然想起了我原先为什么老是失败了,,,,醉了,

好吧,废话少说,作者本身只是一个初学者,再加上这个代码放了一段时间了,注释不一定全对,,(别喷我,,,),

这个是在b站的一个视频里面老师操作的,我个人觉得这个视频很棒,初学者入门是我见过最好的了,我把链接放这里,大家有兴趣可以去看看,https://www.bilibili.com/video/BV1RJ411z7tH,课程名字是,最新Python爬虫项目实战全程实录(完结) #学完这个课所有爬虫都能写
这个项目在这个课程的倒数第三个,百度图片爬取。大家懂不起可以去看视频,这里的博客,我只是作为一个笔记,(经常不小心删代码,,这种打了一堆注释的代码,,我还是有点心疼的,即使它并不是完美也不高级)
溜了,,,,

你可能感兴趣的:(爬虫,项目,python,搜索引擎,pycharm,http)