本站将逐步迁移至新站点,点击访问

Python抓取站酷作品图片并保存至本地

121次阅读
没有评论

思路

1、通过 requests 模块请求网页,获取到网页的源码,其中包含了作品集的 URL

2、通过 BeautifulSoup 提取到作品集的 URL ,返回为列表,使用 for 循环遍历作品集

3、遍历访问作品集时,通过 BeautifulSoup 提取到图片的 URL,进行名称格式化后,返回

4、保存图片的 URL 至本地磁盘

5、遍历多页作品集,使用多线程

嗯。。。思路大概是这个样子吧,新手入门- –

 

模块编写

1、抓取主页(start_app)

Python抓取站酷作品图片并保存至本地

从网页源码中可以看出,其主要内容包含在class为 work-list-box 的这个div内,并且每个作品又是单独包含在 class 为 card-box 这个div内的,所以首先,通过 BeautifulSoup 生成 soup 对象后,使用 soup.find class=work-list-box 找到位于该 class 内的元素,再通过 find_all class= card-box 生成 作品集的一个列表,代码为:

def start_app(self):
    print('[Message]正在抓取 - %s' % self.url)
    try:
        response = requests.get(self.url, headers=self.headers)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, 'lxml')
            page_content = soup.find('div', class_="work-list-box")
            card_box_list = page_content.find_all('div', class_="card-box")
        else:
            print('[Error]文档获取失败,状态为 - %s' % (self.url, response.status_code))
    except Exception as e:
        print(e)

2、抓取内容

1 中 获取到的作品集list,在该模块进行遍历,通过 BeautifulSoup 方法获取到作品集的 URL,标题,作者,其中,标题 + 作者 作为保存图片文件的路径,作品集的URL通过 requests 模块请求,再次抓取作品集内部的图片

Python抓取站酷作品图片并保存至本地

 

def get_content(self, item):
    title = item.find('a', class_="title-content")
    avatar = item.find('div', class_="card-item")
    if title is not None and avatar is not None:
        titlename = title.text
        authorname = avatar.find('a')['title']
        path_str = "[%s]-[%s]" % (authorname, titlename)
        path_str_mk = self.save_path('D:/img/' + self.file_name(path_str))
        href = title['href']
        try:
            html = requests.get(href, headers=self.headers)
            if html.status_code == 200:
                img_url_list = self.get_img_link(html.text)
                if path_str_mk is None:
                    return
                else:
                    for img_url in img_url_list:
                        self.save_img(img_url, path_str_mk)
            print("[Error]文档 %s 获取失败,状态为 - %s," % (href, html.status_code))
        except Exception as e:
            print(e)
def get_img_link(self, html):
    soup = BeautifulSoup(html, 'lxml')
    work_show_box = soup.find('div', class_="work-show-box")
    res = work_show_box.find_all('div', class_="reveal-work-wrap")
    img_list = []
    for item in res:
        img = item.find("img")
        if img is not None:
            img_url = str(img['src']).split('@')[0]
            img_list.append(img_url)
        else:
            print('[Warning]没有图片')
            continue
    return img_list

3、处理保存路径和保存文件名,保存文件

def save_path(self, file_path):
    file_name_s = file_path.split("/")
    file_name = file_name_s[len(file_name_s) - 1]
    file_name_s[len(file_name_s) - 1] = file_name
    path = "/".join(file_name_s)
    if not os.path.exists(path):
        os.mkdir(path)
    return path

def file_name(self, file_name):
    file_stop_str = ['\\', '/', '*', '?', ':', '"', '<', '>', '|']
    for item2 in file_stop_str:
        file_name = file_name.replace(item2, '-')
    return file_name

def save_img(self, url, path):
    download_name = str(path) + '/' + str(url).split('/')[-1]
    res = requests.get(url, headers=self.headers)
    if res.status_code == 200:
        f = open(download_name, 'wb')
        f.write(res.content)
        f.close()
        print("[Message]下载成功 - %s" % download_name)
    else:
        print('[Error]下载失败 - %s' % download_name)

完整代码

# -*- coding:utf-8 -*-
__author__ = 'wx'
import requests,os
from bs4 import BeautifulSoup
import threading
class zcool_img(object):
    def __init__(self,url):
        self.url = url
        self.headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36'
        }
    def start_app(self):
        print('[Message]正在抓取 - %s' % self.url)
        try:
            # 请求主页
            response = requests.get(self.url,headers=self.headers)
            if response.status_code == 200:
                # 返回BeautifulSoup对象
                soup = BeautifulSoup(response.text,'lxml')
                # 寻找作品集div
                page_content = soup.find('div',class_="work-list-box")
                # 在作品集div中,寻找class为card-box,返回即为该页面所有作品集的一个列表
                card_box_list = page_content.find_all('div',class_="card-box")
                # 遍历该列表
                for item in card_box_list:
                    # 执行get_content函数,获取内容
                    self.get_content(item)
            else:
                print('[Error]文档获取失败,状态为 - %s' % (self.url, response.status_code))
        except Exception as e:
            print(e)
    def get_content(self,item):
        # 此处传入的 item 为一个作品集 的源码,通过BeautifulSoup 标签寻找,获取 title avator信息
        title = item.find('a',class_="title-content")
        avatar = item.find('div', class_="card-item")
        if title is not None and avatar is not None:
            titlename = title.text
            authorname = avatar.find('a')['title']
            # 处理保存路径,格式化为 [作品名]-[作者名]
            path_str = "[%s]-[%s]" % (authorname, titlename)
            # 调用路径处理函数,返回最终的路径
            path_str_mk = self.save_path('D:/img/' + self.file_name(path_str))
            # 获取作品集的 URL
            href = title['href']
            try:
                # 请求作品集URL
                html = requests.get(href,headers=self.headers)
                if html.status_code == 200:
                    # 通过 get_img_link函数,得到该作品集下的所有图片URL
                    img_url_list = self.get_img_link(html.text)
                    if path_str_mk is None:
                        return
                    else:
                        # 调用save_img函数,传入图片URL,保存至本地
                        for img_url in img_url_list:
                            self.save_img(img_url,path_str_mk)
                print("[Error]文档 %s 获取失败,状态为 - %s," % (href, html.status_code))

            except Exception as e:
                print(e)
    def save_img(self,url,path):
        download_name = str(path) + '/' + str(url).split('/')[-1]
        res = requests.get(url,headers=self.headers)
        if res.status_code == 200:
            f = open(download_name,'wb')
            f.write(res.content)
            f.close()
            print("[Message]下载成功 - %s" % download_name)
        else:
            print('[Error]下载失败 - %s' % download_name)

    def get_img_link(self,html):
        # BeautifulSoup处理 作品集源码
        soup = BeautifulSoup(html,'lxml')
        # 获取图片
        work_show_box = soup.find('div',class_="work-show-box")
        res = work_show_box.find_all('div',class_="reveal-work-wrap")
        img_list = []
        for item in res:
            img = item.find("img")
            if img is not None:
                img_url = str(img['src']).split('@')[0]
                img_list.append(img_url)
            else:
                print('[Warning]没有图片')
                continue
        return img_list
    def save_path(self,file_path):
        file_name_s = file_path.split("/")
        file_name = file_name_s[len(file_name_s) - 1]
        file_name_s[len(file_name_s) - 1] = file_name
        path = "/".join(file_name_s)
        if not os.path.exists(path):
            os.mkdir(path)
        return path

    def file_name(self,file_name):
        file_stop_str = ['\\', '/', '*', '?', ':', '"', '<', '>', '|']
        for item2 in file_stop_str:
            file_name = file_name.replace(item2, '-')
        return file_name
def main():
    threads = []
    for i in range(1,22):
        url = 'https://www.zcool.com.cn/?p='+ str(i) + '#tab_anchor'
        zcoolOper = zcool_img(url)
        threads.append(threading.Thread(target=zcoolOper.start_app))
    for item in threads:
        item.start()

if __name__ == '__main__':
    main()

运行结果

Python抓取站酷作品图片并保存至本地

Python抓取站酷作品图片并保存至本地

Honest1y
版权声明:本站原创文章,由Honest1y于2018年09月06日发表,共计9661字。
转载提示:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)