python爬漫画(1)—— 如何爬取简单静态网页的图片

  之前写了一个python爬虫爬漫画视频的小程序,在此以一个系列的方式对其中用到的技术进行一个记录

   系列一.简单的静态网页爬取

  这里取的是kuku漫画网,http://comic.kukudm.com

  采用的是requet 访问url,beautifulSoup来解析网站

response = requests.get(url)  #此处的url就是想访问的网站的url 比如随意挑取一部漫画的url
                              #http://comic.kukudm.com/comiclist/2531/
response.encoding = 'gbk' #该网站是gbk编码的,如果采用utf-8会导致乱码
page = BeautifulSoup(response.text, "lxml") #采用BeautifulSoup来进行解析

我们打开网页,查看一下网页的元素,首先我们想获取的是漫画的总话数,这里我们看到,该漫画更新了四话,鼠标移至“妹控姐姐与天然妹妹”,右键查看元素(本人是火狐浏览器),也可以F12寻找到该标签

我们可以看到,包含“妹控姐姐与天然妹妹”的标签 在<dl id=comiclistn>下,<dd>标签下

于是我们获取<dl id=comiclistn>下所有的<dd>标签

total_html = page.find('dl', id='comiclistn')
for i in total_html.find_all('dd'):

 接下来,我们进行漫画的爬取,要进行爬取,需要找到具体每一面漫画对应的url,我们点进一页漫画,观察其url

我们发现其url为上一副图中蓝色高亮<a href =/comiclist/2531/65924/1.htm>中的url,并且翻到下一页我们可以看到,只有最后的1.htm变为了2.htm,也就是那个数字对应了漫画的面数。

所以我们接下来的思路就是获取总的页数,然后放在一个for循环里进行下载就好。

这里我们用与上一步获取漫画总话数相同的思路

只不过这里利用的是漫画跳转的某一页的功能中的总页数信息,我这里采用了字符串切割的方法将总页数提取出来,存储在totalNum中

 response = requests.get(url)
        response.encoding = 'gbk'
        page = BeautifulSoup(response.text, "lxml")
        total_html = page.find('dl', id='comiclistn')
        total_chapter = []
        # 共有多少话
        for i in total_html.find_all('dd'):
            href = i.a['href']
            # 每话进行下载
            # 获取漫画名字
            name = i.get_text()
            name = name[:-6]  # 截掉这个网站目录里面的1 2 3
            # 进入每一话页面
            each_url = 'http://comic.kukudm.com' + href
            tempPage = requests.get(each_url)
            tempPage.encoding = 'gbk'
            tempPic = BeautifulSoup(tempPage.text, "lxml")
            # 找到该话总页数
            tempNum = tempPic.find_all("td")[1]
            tempNum = str(tempNum).split("共", 1)[1]
            tempNum = tempNum.split("页", 1)[0]
            totalNum = int(tempNum)

接着我们开始每一页的下载,一下代码中的q是一个queue类型的变量,在下载阶段我采用了多线程下载以加快速度,我们把提取的url全都放到q中

# 进入该话的每一面
            for pageNum in range(1, totalNum + 1):
                e = everyPageManga()
                # print(each_url)
                everyPageList = str(each_url).split("/")
                everyPageUrl = ""
                # everyPageUrl变成结尾是面数的url
                for n in range(0, len(everyPageList) - 1):
                    everyPageUrl = everyPageUrl + everyPageList[n] + "/"
                everyPageUrl = everyPageUrl + str(pageNum) + ".htm"
                e.url=everyPageUrl
                e.name=name
                e.page=pageNum
                q.put(e)

既然我们已经获取了漫画每一页的url,那接下来我们就来下载这个url的内容

def downloadEveryPage(filepath,q,source):
    e=q.get()
    name=e.name
    pageNum=e.page
    everyPage = requests.get(e.url)
    everyPage.encoding = 'gbk'
    # 通过切割找到漫画的根资源地址
    rootLocation = BeautifulSoup(everyPage.text, "lxml")
    script = rootLocation.find_all('script')[3]
    sourcePart = (str(script)).split("src=", 1)[1]
    sourcePart = sourcePart.split("\"", 3)[2]
    sourcePart = sourcePart.split("\'", 1)[0]
    sourcePart = source + sourcePart
    sourcePic = requests.get(sourcePart)

    # 下载
    with open(filepath+"/" + name + " " + str(pageNum) +"页"+".jpg", "wb") as pic:
        pic.write(sourcePic.content)
    print("{name} 第{pageNum}页 已经下载".format(name=name, pageNum=pageNum))

该函数的参数解释 filepath下载目的路径, q之前提到的栈, 我们点击一页漫画,这里的source值为

source = "http://n5.1whour.com/"

source值获取方式为:

我们进入到漫画中的某一页,F12查看网页元素 发现

为什么需要这个source呢? 我们可以访问这个source与我们加入q之中的url进行组合之后的url,发现网页返回的页面就是该页漫画的图片,而不再有其它的东西,这个url下的页面就是我们真正要下载的。

整个程序的完整代码如下

import requests
from bs4 import BeautifulSoup
import queue
import threading

#此份代码用类来记录漫画的不同属性
class everyPageManga:
    url=""
    name=""
    page=0

def getComicUrl(url,source,q):
    try:
        response = requests.get(url)
        response.encoding = 'gbk'
        page = BeautifulSoup(response.text, "lxml")
        total_html = page.find('dl', id='comiclistn')
        total_chapter = []
        # 共有多少话
        for i in total_html.find_all('dd'):
            href = i.a['href']
            # 每话进行下载
            # 获取漫画名字
            name = i.get_text()
            name = name[:-6]  # 截掉这个网站目录里面的1 2 3
            # 进入每一话页面
            each_url = 'http://comic.kukudm.com' + href
            tempPage = requests.get(each_url)
            tempPage.encoding = 'gbk'
            tempPic = BeautifulSoup(tempPage.text, "lxml")
            # 找到该话总页数
            tempNum = tempPic.find_all("td")[1]
            tempNum = str(tempNum).split("共", 1)[1]
            tempNum = tempNum.split("页", 1)[0]
            totalNum = int(tempNum)
            # 进入该话的每一面
            for pageNum in range(1, totalNum + 1):
                e = everyPageManga()
                # print(each_url)
                everyPageList = str(each_url).split("/")
                everyPageUrl = ""
                # everyPageUrl变成结尾是面数的url
                for n in range(0, len(everyPageList) - 1):
                    everyPageUrl = everyPageUrl + everyPageList[n] + "/"
                everyPageUrl = everyPageUrl + str(pageNum) + ".htm"
                e.url=everyPageUrl
                e.name=name
                e.page=pageNum
                q.put(e)
    except requests.exceptions.ConnectionError:
        print("输入url错误")
        return

def downloadEveryPage(filepath,q,source):
    e=q.get()
    name=e.name
    pageNum=e.page
    everyPage = requests.get(e.url)
    everyPage.encoding = 'gbk'
    # 通过切割找到漫画的根资源地址
    rootLocation = BeautifulSoup(everyPage.text, "lxml")
    script = rootLocation.find_all('script')[3]
    sourcePart = (str(script)).split("src=", 1)[1]
    sourcePart = sourcePart.split("\"", 3)[2]
    sourcePart = sourcePart.split("\'", 1)[0]
    sourcePart = source + sourcePart
    sourcePic = requests.get(sourcePart)

    # 下载
    with open(filepath+"/" + name + " " + str(pageNum) +"页"+".jpg", "wb") as pic:
        pic.write(sourcePic.content)
    print("{name} 第{pageNum}页 已经下载".format(name=name, pageNum=pageNum))


def download(filepath,q,source):
    while True:
        downloadEveryPage(filepath,q,source)
        q.task_done()


def start_download_kuku(url,file_path):
    source = "http://n5.1whour.com/"
    print("开始下载")
    print(url)
    print(file_path)
    q = queue.Queue(999)
    getComicUrl(url,source,q)
    threadNum = 7
    for i in range(0, threadNum):
        downloadThread = threading.Thread(target=download,args=(file_path,q,source))
        downloadThread.setDaemon(True)
        downloadThread.start()
    q.join()

猜你喜欢

转载自blog.csdn.net/RikkaTakanashi/article/details/84187599
今日推荐