python爬虫爬图片

首先这个代码不是俺这个小白写的。但是毕竟学过几天python ,所以大部分还是能看懂。

爬下来5W多张美女图片啊,把我给激动的。

源代码拿过来的时候,因为是多线程,导致一爬,就把我的IP给封了,可能是访问速度太快,网站启动了保护机制。

后面自己加了几个sleep,这个问题就迎刃而解了。

哈哈。

直接上代码,给各位屌丝一饱口福吧!

# _*_coding:utf-8_*_
# author:david.z
import requests
import os
from lxml import etree
from threading import *
from time import sleep
import time

nMaxThread = 3  # 这里设置需要开启几条线程
ThreadLock = BoundedSemaphore(nMaxThread)
print ("kaishi")
gHeads = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
}


class Meizitu(Thread):
    # 构造函数
    def __init__(self, url, title):
        Thread.__init__(self)  # 调用父类构造函数
        self.url = url  # 这里的url在后面的referer中需要使用
        self.title = title

    # 线程开始函数
    def run(self):
        try:
            PhotoUrl, Page = self.GetPhotoUrlAndPageNum()
            if PhotoUrl and Page > 0:
                self.SavePhoto(PhotoUrl, Page)
        finally:  # 当线程执行完成之后释放 说明这个线程已经结束了 不管是异常结束还是正常结束 他都是结束了 那么就需要启动下一个新的线程来执行 新的内容了
            ThreadLock.release()

    def GetPhotoUrlAndPageNum(self):
        html = requests.get(self.url, headers=gHeads)
        # requests.adapters.DEFAULT_RETRIES=5
        if html.status_code == 200:
            time.sleep(3)
            xmlContent = etree.HTML(html.text)
            PhotoUrl = xmlContent.xpath("//div[@class='main-image']/p/a/img/@src")[0][
                       :-6]  # 01.jpg  正好是-6   比如16a01.jpg  这个时候 从右边数到-6正好就是01.jpg
            PageNum = xmlContent.xpath("//div[@class='pagenavi']/a[5]/span/text()")[0]
            return PhotoUrl, int(PageNum)
        else:
            return None, None

    # 保存图片 如果文件夹不存在则创建文件夹
    def SavePhoto(self, url, page):
        savePath = "./photo3/%s" % self.title
        if not os.path.exists(savePath):
            os.makedirs(savePath)
        for i in range(page):
            heads = {
                "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
                "Referer": "%s/%d" % (self.url, i + 1),
                "Accept": "image/webp,image/apng,image/*,*/*;q=0.8"
            }
            j = 0
            while j < 5:
                print("kaishi3")
                time.sleep(4)
                print (u"Download : %s/%d.jpg" % (self.title, i + 1))
                time.sleep(6)
                html = requests.get("%s%02d.jpg" % (url, i + 1), headers=heads)
                if html.status_code == 200:
                    with open(savePath + "/%d.jpg" % (i + 1), "wb") as f:
                        f.write(html.content)
                    break
                elif html.status_code == 404:
                    j += 1
                    time.sleep(4)
                    continue
                else:
                    return None


def main():
    while True:
        try:
            nNum = int(raw_input(u"请输入要下载几页: "))  # 这里是python2的用法 python3可能已经没有raw_input了  建议换成input
            if nNum > 0:
                break
        except ValueError:
            print(u"请输入数字。")
            continue
    for i in range(nNum):
        url = "https://www.mzitu.com/japan/page/%d/" % (i + 1)
        html = requests.get(url, headers=gHeads)
        print("kaishi2")
        time.sleep(4)
        if html.status_code == 200:
            xmlContent = etree.HTML(html.content)
            hrefList = xmlContent.xpath("//ul[@id='pins']/li/a/@href")
            titleList = xmlContent.xpath("//ul[@id='pins']/li/a/img/@alt")
            for i in range(len(hrefList)):
                ThreadLock.acquire()  # 这里使用信号量的原因是 比如当前的设置是3 是为了控制线程数 如果这里没有这个信号量 那么线程会无限启动
                t = Meizitu(hrefList[i], titleList[i])
                t.start()
                time.sleep(6)
                print ("--->:kaishi4")


if __name__ == '__main__':
    main()
原文地址:https://www.cnblogs.com/davidz/p/12630984.html