爬虫福利一 之 27报网MM

爬虫福利一 之 27报网MM《爬虫福利二》点击:https://blog.csdn.net/PY0312刚学爬虫花了4个小时写的,每一步备注的都很清楚,喜欢的朋友自己可以研究研究……目标网站:https://www.27bao.com环境:Python3.x相关第三方模块:requests、lxmlRe:各位在测试时只需要打开终端,使用pythonxxx.py运行即可。源码如下…

大家好,又见面了,我是你们的朋友全栈君。

爬虫福利一 之 27报网MM

爬虫福利一 之 27报网MM《 爬虫福利二 》爬虫福利一 之 27报网MM 点击:https://blog.csdn.net/PY0312


在这里,顺便 送大家一套2020最有趣的Pyhon项目实战视频教程地址: 点击进去就能免费拿,希望大家一起进步!


刚学爬虫花了4个小时写的,每一步备注的都很清楚,喜欢的朋友自己可以研究研究……

目标网站:https://www.27bao.com

环境:Python3.x

相关第三方模块:requests、lxml

Re:各位在测试时只需要打开终端,使用 python xxx.py 运行即可。

源码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time

import requests
from lxml import etree


class MeiZiSpider(object):
    """27 bao website MM spider"""

    def __init__(self):
        self.base_url = 'https://www.27bao.com/meinv/list_1.html'
        self.headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'}

        # 构建url的前缀
        self.url_prefix = 'https://www.27bao.com'

        # 构建第二层url的前缀
        self.inner_url_prefix = 'https://www.27bao.com/meinv/'

        # 构建点开每个MM内部的所有url
        self.inner_url = 'https://www.27bao.com/meinv/56870_{}.html'

        # 文件保存的路径
        self.path = os.getcwd() + '/27baoMM/'

    def send_first_req(self):
        """
        发送第一层请求,返回首页响应的html内容
        :return: 第一层url的html_str
        """

        html_str = requests.get(self.base_url, headers=self.headers).content.decode()

        return html_str

    def get_total_page(self):
        """
        获取网站MM图片总页数
        :return: 图片总页数
        """

        # 模拟发送请求, 返回响应数据(便于提取总页数)
        html_str = self.send_first_req()

        # 将返回的 html字符串 转换为 element对象
        element_obj = etree.HTML(html_str)

        # 提取末页的url, 再切片提取最大页数
        total_page = element_obj.xpath('//*[@id="pages"]/a[9]/@href')[0].split('_')[-1].split('.')[0]
        print('========该网站MM图片目前共有 {} 页========'.format(total_page))

        return total_page

    def get_each_girl_url(self, each_page_url):
        """
        第一层解析 ---> 获取每一页每个MM(第二层)的url
        :param each_page_url: 每一页的url
        :return: 每一页每个MM(第二层)的url和title
        """

        # 用于存放拼接后每个MM的url
        girl_url_list = []

        # 模拟发送请求, 返回响应数据(便于提取url)
        html_str = self.send_request(each_page_url)

        # 将返回的 html字符串 转换为 element对象
        element_obj = etree.HTML(html_str)

        # 提取所有url后缀  ---> 列表
        url_postfix = element_obj.xpath('/html/body/div[2]/div[2]/ul/li/a/@href')

        # 提取每个妹妹的标题, 便于后面命名
        url_title_li = element_obj.xpath('/html/body/div[2]/div[2]/ul/li/p/a/text()')

        # 遍历提取的url列表, 拼接完整的url, 并保存列表中
        for url in url_postfix:
            # 添加拼接后的url到列表
            girl_url_list.append(self.url_prefix + url)
        # print(girl_url_list)

        title_and_url_li = list(zip(url_title_li, girl_url_list))
        # print(title_and_url_li)

        return title_and_url_li

    def send_request(self, url):
        """
        发送第二层请求,返回响应的html内容
        :param url: 每个MM(第二层)的url
        :return: html_str
        """
        try:
            response = requests.get(url, headers=self.headers, timeout=5)
        except:
            return None
        html_str = response.content

        return html_str

    def parse_data(self, html_str):
        """
        第二层解析 ---> 获取当前的每个url
        :param html_str: 第二层响应的html内容
        :return: 具体每张图片的url
        """

        # 将返回的 html字符串 转换为 element对象
        element_obj = etree.HTML(html_str)
        each_image = element_obj.xpath('/html/body/div[3]/center/img/@src')[0]
        # print(each_image)
        return each_image

    def save_file(self, image_data, title, image_name):
        """
        保存图片
        :param image_data: 具体每张图片的数据
        :param title: 具体每个MM的标题
        :param image_name: 具体每张图片的名字
        :return:
        """

        # 如果目录不存在, 就新建
        if not os.path.exists(self.path + title):
            os.makedirs(self.path + title)
        # 切换到新建目录下
        os.chdir(self.path + title)

        with open(image_name, 'wb') as f:
            f.write(image_data)

    def download(self):
        total_page = self.get_total_page()
        # 开循环, 爬取每个页面的每个妹妹的所有图片
        for page in range(1, int(total_page) + 1):
            print('\n正在爬取第 {} 页...\n'.format(page))
            # 构建每一页的url
            each_page_url = 'https://www.27bao.com/meinv/list_{}.html'.format(page)
            title_and_url_li = self.get_each_girl_url(each_page_url)

            # 遍历获取每个妹妹的总url
            for girl_url in title_and_url_li:
                # print(girl_url[1])

                html_str = self.send_request(girl_url[1])
                print('正在爬取的地址: {}'.format(girl_url[1]))

                # 获取目前爬取的MM内部总页数
                inner_total_page = etree.HTML(html_str).xpath('//*[@id="pages"]/a[last()-1]/text()')[0]
                print('\n目前爬取的MM图片共有 {} 张\n'.format(inner_total_page))

                # 循环并构造每一张图片的url, 请求, 解析, 并保存
                image_data = None
                for inner_page in range(1, int(inner_total_page) + 1):
                    print('正在爬取 {} 第 {} 张图片...'.format(girl_url[0], inner_page))
                    # 构造第二页以后的每个url
                    each_image_url = girl_url[1].split('.html')[0] + '_{}.html'
                    if inner_page == 1:
                        # 获取第一页的url, 因为第一页和其他页的规律不一样,所以这里单独出来
                        each_image_url = self.parse_data(html_str)
                        # html_str = self.send_request(each_image_url)
                        image_data = self.send_request(each_image_url)
                    else:
                        each_image_url = each_image_url.format(inner_page)
                        # print(each_image_url)
                        html_str = self.send_request(each_image_url)
                        image = self.parse_data(html_str)
                        image_data = self.send_request(image)

                    # 如果请求图片的url在5秒之内无响应, 立即终止当前妹妹所有url的循环
                    if image_data is None:
                        print('当前MM的url无响应,正在跳转到下一个MM的url\n')
                        break
                    # 拼接保存图片的名称
                    image_name = str(inner_page) + '.jpg'
                    try:
                        # 切换图片保存目录
                        os.chdir(self.path + girl_url[0])
                        # 判断文件是否存在, 存在则不再保存, 跳过
                        if os.path.exists(image_name):
                            print('第 {} 张已保存, 跳过...'.format(inner_page))
                            continue
                    except Exception as e:
                        print('目录 "{}":不存在, 正在新建...'.format(self.path + girl_url[0]))

                    # 保存图片到本地
                    self.save_file(image_data, girl_url[0], image_name)
                # print(image_list)
                if image_data:
                    print('\n{} 的所有图片已全部爬取完毕...\n'.format(girl_url[0]))

                # 休眠5秒中, 避免请求一直处于长连接导致ip被封
                time.sleep(10)


if __name__ == '__main__':
    MeiZiSpider().download()

注意:最后再送大家一套2020最有趣的Pyhon项目实战视频教程地址,点击进去就能免费领取,一定要多练习代码。希望大家一起进步!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/150678.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • TCP的拥塞控制(详解)「建议收藏」

    TCP的拥塞控制(详解)「建议收藏」在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做网络拥塞。在计算机网络中数位链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源。若出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。当输入的负载到达一定程度吞吐量不会增加,即一部分网络资源会丢失掉,网络的吞吐量维持在其所能控制的最大值,转发节点的缓存不够大这造成分…

  • Eclipse改成中文版本「建议收藏」

    Eclipse版本:Neon参考链接:http://www.eclipse.org/babel/downloads.php如果安装完成后,同时保留英文,只需要在快捷方式后添加图片中内容:网页上的详细信息:InstallingthelanguagepacksOpentheinstallwizardwith’Help’>’

  • java 添加 psd_psd缩略图生成上传解决方案「建议收藏」

    java 添加 psd_psd缩略图生成上传解决方案「建议收藏」第一点:Java代码实现文件上传FormFilefile=manform.getFile();StringnewfileName=null;Stringnewpathname=null;StringfileAddre=”/numUp”;try{InputStreamstream=file.getInputStream();//把文件读入StringfilePath=r…

  • Apache中 RewriteRule 规则参数介绍

    Apache中 RewriteRule 规则参数介绍Apache中RewriteRule规则参数介绍 摘要: Apache模块mod_rewrite提供了一个基于正则表达式分析器的重写引擎来实时重写URL请求。它支持每个完整规则可以拥有不限数量的子规则以及附加条件规则的灵活而且强大的URL操作机制。这里着重介绍RewriteRule规则以及参数说明。Apache模块mod_rewrite提供了一个基于正则表达式分析器的重写引擎来实…

  • 分享社群规划全流程sop(基础搭建、日常维…

    分享社群规划全流程sop(基础搭建、日常维…无套路,纯分享!全套社群运营文档,可学习套用相信不少做社群运营的朋友一定会出现过这种情况,微信社群或者QQ社群内的群成员不活跃,整天群里犹如一潭死水,此外还有运营目标不明确、成员不愿积极发言、大部分人入群从不说话等等问题。作为运营狗一定要学会社群规划,今天就给大家带来一份【社群规划全流程sop】,主要包含基础搭建、日常维护、增留转、互动案例等四个步骤,每个步骤都有详细的规划讲解,以及相关案例,非常值得参考学习使用。社群规划全流程sop社群规划全流程sop社…

  • navicat 15.0.22 激活码(最新序列号破解)

    navicat 15.0.22 激活码(最新序列号破解),https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号