爬虫爬取二次元网站美女图片
- 前言
- xpath解析
- 需求分析
- 代码编写
- 总代码
前言
本次需要爬取二次元网站cos板块下的图片
需要用到request模块与lxml模块,所以请提前安装好这两个模块,打开cmd程序输入
request | lxml |
---|---|
pip install request | pip 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).contentwith 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请求的urlurl = '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).textdetail_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:#获取图片的urldata_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:#获取图片的urldata_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).contentwith 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 titleif __name__=="__main__":start = time.time()etree = html.etree#ajax请求的urlurl = '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).textdetail_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:#获取图片的urldata_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)