python-selenium模块爬取动态网址实例---------【下载漫画码上面的漫画】

原标题 :运用Python爬虫下载漫画码上面的漫画

前言

看过小编博客的读者应该知道,小编写的这篇博客:Python爬虫经常爬不到数据,或许你可以看一下小编的这篇文章 有一点不足,就是最后讲到的那个动态加载问题,那里没有给出一个好一点的实例,现在,小编把那个空缺补全一下,希望读者喜欢!

首先,先讲明一点,在这里插入图片描述

1.需要的Python模块和基本用法

selenium、requests、os、time模块
其中selenium模块我不讲相信读者也已经知道了吧!requests模块在这里主要的作用是负责下载漫画图片,本来小编打算是运用urllib.request里面的urlretrieve方法下载的,但是这个程序代码比较特别,需要添加一个请求头,不然就会出现403错误,所以小编选择了requests模块。
os模块在这里的作用是创建文件夹,time模块主要是用来休眠,这个模块是必须有的,否则有个时候程序会报错,为了避免出现,所以小编在这里用了time模块。

2.实现程序代码的思路

在这里,首先给出这个网址:漫画码
在实现整个过程当中,除了最后那个下载漫画图片是用了requests模块之外,其他基本是运用selenium模块实现的。也就是说完成整个过程基本上是爬取动态网址的数据。

在这里插入图片描述
首先,应该模拟浏览器在搜索框中输入相应的内容,然后再按电脑键盘的Enter 键来到另外一个界面,小编输入的是:斗破苍穹 ,接下来就是这个界面了。
在这里插入图片描述
怎样实现呢?
按电脑键盘的F12键或者鼠标右键 检查 ,来到开发者模式,得到搜索框的位置,再这里小编用的是xpath语法,如下:
在这里插入图片描述
可以发现,这个搜索框中默认是有内容的,如何处理呢?

seek = self.driver.find_element_by_xpath('.//div[@class="search-wrap"]/input')  # 搜索输入框
seek.clear()  # 清空输入框中的内容

也就是这样了,在这个输入框中输入相应的内容,由于这个网址没有搜索按钮,所以这里需要导入这个

from selenium.webdriver.common.keys import Keys

然后使用其中的一个属性,如下:

seek.send_keys(Keys.ENTER)

这样就可以模拟浏览器按Enter键了。
那么怎样再搜索得到内容中选择自己想看的内容呢?和上面一样,找到相应的位置,如下:
在这里插入图片描述
由于这里搜索得到的结果不可能是一个,所以使用的方法如下:

seek_out = self.driver.find_elements_by_xpath('.//ul[@id="J_comicList"]/li/a')  # 搜索结果

这里的find_elements_by_xpath 得到的结果是一个列表格式的数据
之后再使用.click()方法选择其中的一个就可以了,小编选择的是第一个,来到接下来的这个界面,
在这里插入图片描述
这个时候可以发现这是一个新的界面,也就是这里要变化一下这个窗口,代码如下:

self.driver.switch_to.window(self.driver.window_handles[-1])

接下来,就是得到这个界面下的所有漫画章节了,在这里插入图片描述
别看这个界面只有十多章节的漫画,可是查看一下源代码可以发现,所有漫画章节都是在这个界面下,不过也是动态加载的,读者看一下就知道了。
在这里插入图片描述

Hrefs_List = self.driver.find_elements_by_xpath('.//ol[@class="chapter-list col-4 text"]/li/a')

选择其中的一章节漫画进入,可以发现就是漫画了,不过也是动态加载的,另外,如果直接使用xpath语法得到这些图片位置的话,输出的时候只能有部分图片的下载网址,或许 这就是动态网址的神奇之处了,只有在滚动条下滑的时候,才可能得到全部下载网址,难道没有简单的方法了吗?
肯定是有的,那就是得到一章节漫画下面的漫画页数,然后运用字符串拼接就可以基本实现了,
在这里插入图片描述
实现下载代码如下:

 str2=driver.find_element_by_xpath('.//p[@class="acgn-reader-chapter__index-footer"]').text
 end=int(str2.split('/')[-1])   # 得到一节漫画中的总页数

 List2=driver.find_elements_by_xpath('.//div[@class="acgn-reader-chapter__item-box"]/div/div/img')
 url=List2[0].get_attribute('src')   # 网址

 path2 = self.path + '\{}'.format(self.Name[i])

 try:
     os.mkdir(path=path2)
 except Exception as e:
     print(e)
 # 下载一节漫画中的所有图片
 self.headers['referer']=self.List[i]
 for j in range(1,end+1):  # 对网址进行字符串的拼接
     url_start=url.rfind('/')+1
     url_end=url.rfind('.jpg')
     url=url[:url_start]+str(j)+url[url_end:]  # 图片下载网址
     response=requests.get(url=url,headers=self.headers)
     with open(file=path2+'\{}.jpg'.format(j),mode='wb') as f:
         f.write(response.content)

 driver.close()
 time.sleep(1)
 print('*'*int(random()*10)+'->已下载{}'.format(self.Name[i]))

3.完整代码和运行结果

from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from random import random
import requests
import time
import os

class Cartoon(object):
    def __init__(self, keyword,path):
        self.url2 = 'https://www.manhuama.net/'
        self.driver = webdriver.Chrome()
        self.keyword = keyword
        self.List=list()
        self.Name=list()
        self.headers={
    
    'referer':''}
        self.path=path

    def GetOutcome(self):
        self.driver.get(self.url2)
        self.driver.implicitly_wait(30)
        seek = self.driver.find_element_by_xpath('.//div[@class="search-wrap"]/input')  # 搜索输入框
        seek.clear()  # 清空输入框中的内容
        seek.send_keys(self.keyword)
        seek.send_keys(Keys.ENTER)
        time.sleep(1)  # 休眠一秒

        seek_out = self.driver.find_elements_by_xpath('.//ul[@id="J_comicList"]/li/a')  # 搜索结果
        name_list = list()
        for i in range(len(seek_out)):
            print('[{}]-#$&@>{}'.format(i + 1, seek_out[i].get_attribute('title')))
            name_list.append(seek_out[i].get_attribute('title'))


        id = int(input('请输入想看的漫画序号:'))
        print('你选择的是:{}'.format(name_list[id - 1]))
        seek_out[id - 1].click()

    def GetHrefs(self):  # 定义方法,用于得到一部漫画下面的所以章节的链接和名称
        self.GetOutcome()
        self.driver.switch_to.window(self.driver.window_handles[-1])
        print('referer:{}'.format(self.driver.current_url))
        Hrefs_List = self.driver.find_elements_by_xpath('.//ol[@class="chapter-list col-4 text"]/li/a')
        # print(len(Hrefs_List))
        for i in range(len(Hrefs_List)):
            if (i+1)%2==0:
                print()
            print('[{}]-#$@->{}'.format(i + 1, Hrefs_List[i].get_attribute('title')),end='\t\t\t')
            self.List.append(Hrefs_List[i].get_attribute('href'))
            self.Name.append(Hrefs_List[i].get_attribute('title'))

        id2, id3 = 0, 0
        print()
        str2 = input('请输入想看的漫画序号\n(注意格式:1. 2,3  表示 2~3 中间是英文逗号  \n 2. 单独输入一个 n 表述 1~n)\n输入:')
        List = str2.split(',')
        if len(List) == 1:
            id3 = int(List[0])
        else:
            id2, id3 = int(List[0]) - 1, int(List[1])

        return id2,id3

    def Download(self):
        id2,id3=self.GetHrefs()
        self.driver.quit()  # 关闭浏览器
        for i in range(id2,id3):
            driver = webdriver.Chrome()
            driver.get(url=self.List[i])
            driver.implicitly_wait(30)

            str2=driver.find_element_by_xpath('.//p[@class="acgn-reader-chapter__index-footer"]').text
            end=int(str2.split('/')[-1])   # 得到一节漫画中的总页数

            List2=driver.find_elements_by_xpath('.//div[@class="acgn-reader-chapter__item-box"]/div/div/img')
            url=List2[0].get_attribute('src')   # 网址

            path2 = self.path + '\{}'.format(self.Name[i])

            try:
                os.mkdir(path=path2)
            except Exception as e:
                print(e)
            # 下载一节漫画中的所有图片
            self.headers['referer']=self.List[i]
            for j in range(1,end+1):  # 对网址进行字符串的拼接
                url_start=url.rfind('/')+1
                url_end=url.rfind('.jpg')
                url=url[:url_start]+str(j)+url[url_end:]  # 图片下载网址
                response=requests.get(url=url,headers=self.headers)
                with open(file=path2+'\{}.jpg'.format(j),mode='wb') as f:
                    f.write(response.content)

            driver.close()
            time.sleep(1)
            print('*'*int(random()*10)+'->已下载{}'.format(self.Name[i]))

        print('下载完毕!')



if __name__ == '__main__':
    print('----------------------漫画码------------------------')
    keyword = input('请输入你想看的漫画名称:')
    path=input('请输入你想创建的文件夹的绝对路径:')
    try:
        os.mkdir(path=path)
    except Exception as e:
        print(e)
    a = Cartoon(keyword=keyword,path=path)
    a.Download()

运行结果如下:

运用Python爬虫下载漫画码网址的漫画

注意:读者在运行代码时,注意输入格式问题,否则会报错的,还有,读者如果要运行小编的这个代码时注意下载页数尽量输入小点,这样运行时间会少点,而且不会出现错误(小编在这里没有进行异常处理),最好的还是不会对服务器造成很大的负担,作为一名合格的Python爬虫爱好者,文明爬虫,从我做起!

4.总结

看了一下运行结果,读者是不是觉得很神奇。
另外,小编觉得运用selenium模块的 page_source方法输出代码,读者看到的那个代码不一定是正确的,这个时候运用find_element_方法里面的一种可以得到输出代码中没有那部分数据。读者可以自行完成这个程序代码试一试,可以发现的,哈哈!如果读者觉得小编的这篇博客还不错!点个赞在走吧!谢谢!

猜你喜欢

转载自blog.csdn.net/qq_45404396/article/details/108913283