python爬取百度图片

1.查询数据

打开网页。

https://cn.bing.com/images/search?q=%E7%99%BE%E5%BA%A6%E5%9B%BE%E7%89%87&form=HDRSC2&first=1&cw=1585&ch=924

 我们右键查看网页源代码,发现能找到我们需要的img衔接,但是这是一个动态网页。我们每次向下滑动网页,会发现图片更新,而图片更新一般伴随着异步请求。

并且我们打开控制台,如下图所示:

1.点击网络 2.点击Fetch/XHR 

python爬取百度图片_第1张图片

 随着向下滑动:

下图红框异步请求次数增多。

python爬取百度图片_第2张图片

我们将异步请求衔接,在另一个标签页打开。

发现这个异步请求的响应数据有我们需要的图片。

2.请求数据

我们在上面知道是一个动态网页之后,并且找到请求img的地址之后,我们是不是要探寻请求url的规律,发现是如何向下滚动,出现新的图片?

经过查找对比,发现这几个请求参数,新的请求会发生变化。

python爬取百度图片_第3张图片

 然后,我们通过对这几个参数修改进行请求,发现实际起作用的是first。也就是图片起始索引。

另外,q也就是我们搜索的数据进行url编码之后的东西。

3.解析数据

我们找到我们找寻的图片在哪里,但是发现请求响应的是一堆html + css + js代码,因此我们需要对其进行过滤,只找到我们需要的img的url。

我们在打开刚才的那个异步请求url,查看页面源代码。

将前端代码,粘贴到在线 HTML 格式化工具,HTML 代码美化工具 - 在线工具-wetools.com微工具

这个html格式化工具里面,格式化后,将格式化后的代码,粘贴到vscode里面。 

 我们查看代码发现,我们需要img的url,是在下图所示的层级结构里面:

python爬取百度图片_第4张图片 更往上的html层级结构为:

python爬取百度图片_第5张图片

 因此我们的python爬虫代码可以这样写:

from lxml import etree
import requests
from fake_useragent import UserAgent


if __name__ == '__main__':
    headers = {
        'User-Agent': UserAgent().random
    }

    url = "https://cn.bing.com/images/async?q=%e7%99%be%e5%ba%a6%e5%9b%be%e7%89%87&first=162" \
          "&count=35&cw=1177&ch=909&relp=35&apc=0&datsrc=I&layout=RowBased&mmasync=1&dgState=x*740_y*940_h*180_c*3_i*106_r*20&" \
          "IG=1EA071CC53E44DFA8101AF041D481594&SFX=4&iid=images.5563"
    # 请求响应数据
    html = requests.get(url=url,headers=headers).text
    p = etree.HTML(html)
    img_list = []
    # 解析响应数据
    ul_list = p.xpath('//ul[@data-row]')     # 基准表达式
    for ul in ul_list:
        li_list = ul.xpath('.//li[@data-idx]')
        for li in li_list:
            img1_list = list(li.xpath('.//img[contains(@class,"mimg")]/@src'))
            img2_list = list(li.xpath('.//img[contains(@class,"cimg")]/@src'))
            for img1 in img1_list:
                img_list.append(img1)
            for img2 in img2_list:
                img_list.append(img2)
    print(img_list)

4.将图片保存到本地

我们将上述img 衔接,再次进行请求并下载到本地。

    # 保存图片
    def save_images(self, img_list, dir_path, q):
        # 不存在,创建目录
        dir_path = dir_path + '/' + q + "/"
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        i = 1
        for img in  img_list:
           img_path = '{}{}-{}.jpg'.format(dir_path,q,i)
           self.save_image(img_path,img)
           i += 1

     # 保存图片
    def save_image(self,img_path,img):
        html = requests.get(url=img,headers=self.get_headers()).content
        with open(img_path,'wb') as f:
            f.write(html)

4.完整代码

from lxml import etree
import requests
from fake_useragent import UserAgent
from urllib import parse
import os



class BaiduSpider:
    def __init__(self):
        self.url = "https://cn.bing.com/images/async?q={}&first={}&count=35&cw=1177&ch=909" \
                   "&relp=35&apc=0&datsrc=I&layout=RowBased&mmasync=1"

    # 获取请求头
    def get_headers(self):
        return {
            'User-Agent': UserAgent().random
        }

    # 获取响应数据
    def get_html(self, q, first):
        q = parse.quote(q)
        url = self.url.format(q, first)
        html = requests.get(url=url, headers=self.get_headers()).text
        return html

    # 解析响应数据
    def parse_html(self, html):
        p = etree.HTML(html)
        img_list = []
        # 基准表达式
        ul_list = p.xpath('//ul[@data-row]')
        for ul in ul_list:
            li_list = ul.xpath('.//li[@data-idx]')
            for li in li_list:
                img1_list = list(li.xpath('.//img[contains(@class,"mimg")]/@src'))
                img2_list = list(li.xpath('.//img[contains(@class,"cimg")]/@src'))
                for img1 in img1_list:
                    img_list.append(img1)
                for img2 in img2_list:
                    img_list.append(img2)

        print(img_list)
        return img_list

    # 保存图片列表
    def save_images(self, img_list, dir_path, q):
        # 不存在,创建目录
        dir_path = dir_path + '/' + q + "/"
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        i = 1
        for img in  img_list:
           img_path = '{}{}-{}.jpg'.format(dir_path,q,i)
           self.save_image(img_path,img)
           i += 1

     # 保存图片
    def save_image(self,img_path,img):
        html = requests.get(url=img,headers=self.get_headers()).content
        with open(img_path,'wb') as f:
            f.write(html)

    # 入口函数
    def run(self):
        q = input("请输入搜索内容:")
        first = int(input("请输入起始页数:"))
        dir_path = "../img"
        html = self.get_html(q, first)
        img_list = self.parse_html(html)
        self.save_images(img_list, dir_path, q)


if __name__ == '__main__':
    bds = BaiduSpider()
    bds.run()

你可能感兴趣的:(#,爬虫,python,开发语言)