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