美文网首页IT类作者联盟程序员
不巧看到这篇文章,那就送你2000套妹子图吧!

不巧看到这篇文章,那就送你2000套妹子图吧!

作者: 不学无术丶 | 来源:发表于2019-07-13 20:48 被阅读33次

这事要从前不久说起,在学会用Python爬取小说(文字信息)之后,我把目标转移到了爬取图片上,上网一搜:Python 图片爬虫。大部分搜索结果都是爬取妹子图站点,看来广大的互联网朋友对美好事物还是别有一番追求啊!哈哈哈哈......就这样,我确定了目标:爬取妹子图整站数据! 不断折腾就有了这篇文章。

step 1 网页分析

  • 站点首页有24个图集(其余几个为广告位,真鸡贼.....)和页码1-225,每页的网址仅有末位数字不同,且数字对应页数,呈递增规律
  • 点击任意图集,可以看到该图集包含的所有图片网页(该网页不仅包含我们所需的图片,还有其他杂碎信息),网页链接同样有规律。另外,每个图集包含的图片张数也不一样

step 2 思路

  • 循环遍历站点所有页码,同时获取每页中所有图集的入口链接和图集名称(用于命名文件夹保存图片)
def get_url(page_num):
        response = requests.get('https://www.mzitu.com/page/{}/'.format(page_num), headers=headers)
        html = etree.HTML(response.text)
        pics_titles = html.xpath('//*[@id="pins"]/li/span[1]/a/text()')        # 获取图集名称
        pics_links = html.xpath('//*[@id="pins"]/li/a/@href')                  # 获取图集链接
        directory = 'D:\Mzitu'                                                 # 事先手动在D盘创建一个文件夹,随意
        for pics_title, pics_link in zip(pics_titles, pics_links):             # 让图集名称和图集链接一一对应
            try:
                if os.path.isdir(directory):
                    os.mkdir(os.path.join(directory, pics_title))              # 以图集名称创建文件夹
                    download(pics_title, pics_link, page_num)                  # 调用下载函数 并传入图集名称、图集链接和页码
            except:
                pass
  • 请求每个图集的入口链接,获取图片的张数,循环拼接每张图片的网页链接并请求,从而获取所有图片的真实链接,也可同时获取所有图片的名称,在这里,我是根据图片名称的规律采用拼接的方式获取,用以命名图片文件
def download(pics_title, pics_link, page_num):
    response0 = requests.get(pics_link, headers=headers)
    html_0 = etree.HTML(response0.text)
    max_page = html_0.xpath('/html/body/div[2]/div[1]/div[4]/a[5]/span/text()')[0]    # 每套图包含的图片张数
    for j in range(1, int(max_page) + 1):
        url = pics_link + '/' + str(j)  # 拼接每张图片的网页链接
        response1 = requests.get(url, headers=headers)
        html_1 = etree.HTML(response1.text)
        pic_link = html_1.xpath('/html/body/div[2]/div[1]/div[3]/p/a/img/@src')[0]   # 获取每张图片的链接
        response2 = requests.get(pic_link, headers=headers)                          # 向图片单独发送请求
        file_name = 'D:\Mzitu\\' + pics_title + '\\' + pics_title + str(j) + '.jpg'  # 以图片标题创建文件
        with open(file_name, 'wb') as f:                                             # 保存图片
            f.write(response2.content)
        print('第%s页' % page_num, pics_title, "第%s张已下载完成" % j)

以上两步就能成功获取一套一套的妹子图了!只是爬取速度一般,如果你能接受,也会有不错的收获。最后,提一下运用多线程加速爬虫(小弟不才,只略知一二,望大佬指点!):

  • 如果直接采用多线程,比如:每个图集创建一个线程去爬取,那么在一个大循环中,会创建24个不等的线程去爬取图片,妹子图这个站点还是有反爬机制的,这样做会触发两个错误:1.远程主机强迫关闭现有的连接。2.爬取到的图片全为空文件。
  • 发现这个坑之后,我控制多线程的并发数量,每次并发5或10个线程,结果成功了!爬取速度有一定的提升,但还有改进空间,日后再说~

完整代码:

# -*- coding: UTF-8 -*-
import requests
from lxml import etree
import threading
import queue
import os


headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36',
    "Referer": "https://www.mzitu.com/",
    }


def get_url(page_num):
        response = requests.get('https://www.mzitu.com/page/{}/'.format(page_num), headers=headers)
        html = etree.HTML(response.text)
        pics_titles = html.xpath('//*[@id="pins"]/li/span[1]/a/text()')        # 获取图集名称
        pics_links = html.xpath('//*[@id="pins"]/li/a/@href')                  # 获取图集链接
        directory = 'D:\Mzitu'                                                 # 事先手动在D盘创建一个文件夹,随意
        for pics_title, pics_link in zip(pics_titles, pics_links):             # 让图集名称和图集链接一一对应
            try:
                if os.path.isdir(directory):
                    os.mkdir(os.path.join(directory, pics_title))              # 以图集名称创建文件夹
                    download(pics_title, pics_link, page_num)                  # 调用下载函数 并传入图集名称和图集链接
            except:
                pass


def download(pics_title, pics_link, page_num):
    response0 = requests.get(pics_link, headers=headers)
    html_0 = etree.HTML(response0.text)
    max_page = html_0.xpath('/html/body/div[2]/div[1]/div[4]/a[5]/span/text()')[0]    # 每套图包含的图片张数
    for j in range(1, int(max_page) + 1):
        url = pics_link + '/' + str(j)  # 拼接每张图片的网页链接
        response1 = requests.get(url, headers=headers)
        html_1 = etree.HTML(response1.text)
        pic_link = html_1.xpath('/html/body/div[2]/div[1]/div[3]/p/a/img/@src')[0]   # 获取每张图片的链接
        response2 = requests.get(pic_link, headers=headers)                          # 向图片单独发送请求
        file_name = 'D:\Mzitu\\' + pics_title + '\\' + pics_title + str(j) + '.jpg'  # 以图片标题创建文件
        with open(file_name, 'wb') as f:                                             # 保存图片
            f.write(response2.content)
        print('第%s页' % page_num, pics_title, "第%s张已下载完成" % j)


class MM(threading.Thread):                # 创建一个子类,继承多线程父类threading.Thread
    def __init__(self, page_num, queue):
        threading.Thread.__init__(self)
        self.queue = queue                # 队列
        self.page_num = page_num          # 页数

    def run(self):
        try:
            get_url(self.page_num)        # 在这里调用get_url()函数
        except Exception as e:
            print(e)
        finally:
            self.queue.get()
            self.queue.task_done()


def main():
    q = queue.Queue(10)                   # 设置10个并发线程数,速度还行,可自行尝试修改
    for page_num in range(226):
        q.put(page_num)
        t = MM(page_num, q)
        t.start()
    q.join()


if __name__ == '__main__':
    main()
成果图

相关文章

  • 不巧看到这篇文章,那就送你2000套妹子图吧!

    这事要从前不久说起,在学会用Python爬取小说(文字信息)之后,我把目标转移到了爬取图片上,上网一搜:Pytho...

  • 2018-07-26

    送你 雨一直下 平凡之路 当 那就这样吧

  • 看到这篇,就去睡吧

    不拼一点,总觉得会被淘汰。不乐一乐,总觉得今天不够治愈。 你在,不得已熬夜,还是习惯性熬夜。 到后半夜的时候,你是...

  • 累了吗?那就看看这篇文章吧

    断更了这么久,或许我已经快从你们的印象里慢慢的在消失吧。人人都承认时间是治愈一切的良药,人人也都认为时间可以改变一...

  • [你成坚持社群]17/21 职业发展的正确姿势

    好巧不巧,今天又读到一篇职业方面的文章?可能是因为年终的关系吧,总会对自己的职场生活进行一些反思。这篇文章提供的几...

  • 今天必须发这个

    今天是妹子们的节日,而测试应该是妹子们扎堆的行业,所以今天我必须发一个。祝看到这篇文章的妹子们节日快乐,愿你一直1...

  • 发散思维和逆向思维

    成图构思:看到这篇文,想起我曾写过《不想作温水里的青蛙,那就终生学习吧》一文,曾对人生处于的这三种区域作过论述,而...

  • 就叫不巧吧

    前几天晚上在宿舍躺着睡不着觉就一起聊天。 突然说到有多久没跟人吵过架了,我差不多有几年没跟人吵过架了吧,觉得,吵架...

  • scrapy里面item传递数据后数据不正确的问题

    在上篇文章《python3 + scrapy 爬取妹子图 (meizitu.com)》中,我爬取了妹子图网站的图片...

  • 新人,就应该有新人的样子

    文/乔安姑娘 这周,我劝退了一位入职了三周的妹子,也许这位妹子会很讨厌我,但是希望有幸看到这篇文章,自己心里有些安...

网友评论

    本文标题:不巧看到这篇文章,那就送你2000套妹子图吧!

    本文链接:https://www.haomeiwen.com/subject/pcmmkctx.html