爬虫爬取二次元网站美女图片

爬虫爬取二次元网站美女图片

前言

本次需要爬取二次元网站cos板块下的图片
需要用到request模块与lxml模块,所以请提前安装好这两个模块,打开cmd程序输入

requestlxml
pip install requestpip install lxml

xpath解析

xpath解析:最常用最便捷高效的一种解析方式,通用性。
-xpath解析原理:
- 1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中
- 2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获
- 环境的安装:
- pip install lxml
- 如何实例化一个etree对象:from lxml import html etree = html.etree
- 1.将本地的html文档中的源码数据加载到etree对象中:
etree.parse(filePath)
- 2.可以将从互联网上获取的页面源码数据加载到该对象中
etree.HTML(‘page_text’)
- xpath(‘xpath表达式’)
- xpath表达式
- /:表示的是从根节点开始定位。表示的是一个层级
- //:表示的是多个层级,可以表示从任意位置开始定位
- 属性定位://div[@class=“song”] tag[@attrName=“attrValue”]
- 索引定位://div[@class=“fixedNav”]/div[2] 索引是从1开始的。
- 取文本:
- /text()获取的是标签中直系的文本内容
- //text()标签中非直系的文本内容(所有的文本内容)
- 取属性
- @attrName ==> div/@attrName

需求分析

首先打开网站,点击下一页,会发现网站的url是没有变化的
第一页:

在这里插入图片描述

第二页:

在这里插入图片描述
说明网站的内容是动态加载的,需要获取网站的ajax请求到的json数据,在网站页面点击鼠标右键,点击检查,在点击Network,最后点击XHR,这是用来获取ajax请求的。使其如下图一样
在这里插入图片描述
然后点击第二页,会有这样的请求
在这里插入图片描述
请求的url是:https://www.hmecy.com/wp-admin/admin-ajax.php?action=zrz_load_more_posts
请求方式的:post
请求携带的参数是:type: tag42,paged: 2

点击请求的Response,会发现请求返回信息中有一组html数据,这组html数据中就包含如下板块的内容
这样咱们就获取到了页面的信息

接下来随便点击一个标签,进入她的详情页,咱们要获取标题和下载图片,如图
在这里插入图片描述
你会发现它的图片都在id为‘content-innerText’的div中
标题在h1标签中
在这里插入图片描述

代码编写

首先导包

import requests
from lxml import html
import os
from multiprocessing.dummy import Pool
import time

本次需要用到三个函数

1、down_img

#下载图片的函数,使用多线程下载
def down_img(arr):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
    }
    content = requests.get(url=arr[1][0], headers=headers).content
    with open(arr[0], 'wb')as fp:
        fp.write(content)
    print("下载完成一张")
    time.sleep(0.3)

arr参数里面包含需要图片文件的路径和url网址,访问url得到其中的二进制数据,再将其下载到指定文件内

2、correct_title

#处理图片文件夹的标题
def correct_title(title):
    error_set = ['/', '\\', ':', '*', '?', '"', '|', '<', '>']
    for c in title:
        if c  in error_set:
            title = title.replace(c, '')
    return title

该函数用于纠正文件夹的标题,因为:
在这里插入图片描述
需要将获得的标题进行修改,将其中的非法关键词换为空

3、main

if __name__=="__main__":
    start = time.time()
    etree = html.etree

    #ajax请求的url
    url = 'https://www.hmecy.com/wp-admin/admin-ajax.php?action=zrz_load_more_posts'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
    }
    #所有图片的url链接储存在这里
    all_url = []
    if not os.path.exists('./erciyuan'):
        os.mkdir('./erciyuan')

    #下载前4页的图片,可以根据自己需要更改循环次数
    for num in range(1,5):
        data = {
            'type': 'tag42',
            'paged': str(num)
        }
        #获取请求到的json函数
        response = requests.post(url=url,headers=headers,data=data).json()
        #分析json函数,发现html代码在key为msg的value中
        response = str(response['msg'])
        
        tree = etree.HTML(response)
        data_list = tree.xpath('//a[@class="link-block"]/@href')
        for urls in data_list:
            page_text = requests.get(url=urls,headers=headers).text
            detail_tree = etree.HTML(page_text)
            #获取标题
            title = detail_tree.xpath('//*[@id="post-single"]/h1/text()')
            #修改标题
            titles = correct_title(str(title))
            #存储的文件夹路径
            paths = './erciyuan/' + str(titles)
            url_list = detail_tree.xpath('//*[@id="content-innerText"]//img')
            data_ins = []
            i = 0
            #创建文件夹
            if not os.path.exists(paths):
                os.mkdir(paths)
            for ins in url_list:
                #获取图片的url
                data_url = ins.xpath('./@src')
                #图片的存储路径
                path = paths +'/'+ str(i) +'.jpg'
                i=i+1
                #将路径与图片的url存储到all_url中,方便后面使用多线程下载
                all_url.append([path,data_url])
    #创建4个线程
    pool = Pool(4)
    #将函数与all_url列表放入线程
    pool.map(down_img,all_url)
    print(time.time()-start)

访问ajax请求的url,传入对应的参数,若想访问其他板块,改变对应的参数即可,分析其中的json数据
在这里插入图片描述
html代码都在key为msg的value中,获取该信息,对其进行xpath解析,得到所有详情页对应的url

data_list = tree.xpath('//a[@class="link-block"]/@href')

访问详情页的url,再通过xpath解析,获取文章的标题和该页面的img列表

title = detail_tree.xpath('//*[@id="post-single"]/h1/text()')
url_list = detail_tree.xpath('//*[@id="content-innerText"]//img')

对列表进行循环

            for ins in url_list:
                #获取图片的url
                data_url = ins.xpath('./@src')
                #图片的存储路径
                path = paths +'/'+ str(i) +'.jpg'
                i=i+1
                #将路径与图片的url存储到all_url中,方便后面使用多线程下载
                all_url.append([path,data_url])

对img解析xpath解析,获取其中的src属性值,再给其一个存储路径,存储到all_url中
最后使用多线程进行下载。

总代码

import requests
from lxml import html
import os
from multiprocessing.dummy import Pool
import time

#下载图片的函数,使用多线程下载
def down_img(arr):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
    }
    content = requests.get(url=arr[1][0], headers=headers).content
    with open(arr[0], 'wb')as fp:
        fp.write(content)
    print("下载完成一张")
    time.sleep(0.3)

#处理图片文件夹的标题
def correct_title(title):
    error_set = ['/', '\\', ':', '*', '?', '"', '|', '<', '>']
    for c in title:
        if c  in error_set:
            title = title.replace(c, '')
    return title

if __name__=="__main__":
    start = time.time()
    etree = html.etree

    #ajax请求的url
    url = 'https://www.hmecy.com/wp-admin/admin-ajax.php?action=zrz_load_more_posts'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
    }
    #所有图片的url链接储存在这里
    all_url = []
    if not os.path.exists('./erciyuan'):
        os.mkdir('./erciyuan')

    #下载前4页的图片,可以根据自己需要更改循环次数
    for num in range(1,5):
        data = {
            'type': 'tag42',
            'paged': str(num)
        }
        #获取请求到的json函数
        response = requests.post(url=url,headers=headers,data=data).json()
        #分析json函数,发现html代码在key为msg的value中
        response = str(response['msg'])

        tree = etree.HTML(response)
        data_list = tree.xpath('//a[@class="link-block"]/@href')
        for urls in data_list:
            page_text = requests.get(url=urls,headers=headers).text
            detail_tree = etree.HTML(page_text)
            #获取标题
            title = detail_tree.xpath('//*[@id="post-single"]/h1/text()')
            #修改标题
            titles = correct_title(str(title))
            #存储的文件夹路径
            paths = './erciyuan/' + str(titles)
            url_list = detail_tree.xpath('//*[@id="content-innerText"]//img')
            data_ins = []
            i = 0
            #创建文件夹
            if not os.path.exists(paths):
                os.mkdir(paths)
            for ins in url_list:
                #获取图片的url
                data_url = ins.xpath('./@src')
                #图片的存储路径
                path = paths +'/'+ str(i) +'.jpg'
                i=i+1
                #将路径与图片的url存储到all_url中,方便后面使用多线程下载
                all_url.append([path,data_url])
    #创建4个线程
    pool = Pool(4)
    #将函数与all_url列表放入线程
    pool.map(down_img,all_url)
    print(time.time()-start)

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值