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

    科技2022-07-11  103

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

    前言

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

    首先,先讲明一点,

    文章目录

    原标题 :运用Python爬虫下载漫画码上面的漫画1.需要的Python模块和基本用法2.实现程序代码的思路3.完整代码和运行结果4.总结

    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_方法里面的一种可以得到输出代码中没有那部分数据。读者可以自行完成这个程序代码试一试,可以发现的,哈哈!如果读者觉得小编的这篇博客还不错!点个赞在走吧!谢谢!

    Processed: 0.010, SQL: 8