本文参考了“[Python爬虫]使用Python爬取动态网页-腾讯动漫(Selenium)”——“http://www.sohu.com/a/225094990_491081”




首先进行第一步网页分析,腾讯动漫的网址很容易能看出规律,以《一人之下》为例; 进入该漫画的第一话与第二话:




* http://ac.qq.com/ComicView/index/id/622439/cid/1

* http://ac.qq.com/ComicView/index/id/622439/cid/2




最开始因为查看不了网页源代码,于是想到了抓包分析,不过后来第一个页面只抓到了三个图片网址,于是改用了控制台查看源代码,具体怎么操作参照第一行链接.


这个时候开始进行爬虫代码编写,在对第一页爬取就出现了503错误,随后对爬取得到的网址进行分析发现它与利用抓包工具抓取的有一些区别,也就说源代码中的网址并不是这些图片的真实地址:


    http://ac.tc.qq.com/store_file_download?buid=15017&uin=1439609736&dir_path=/&name=15_11_35_92855d1fc960f772d0096651eb5797e0_2224.ori
针对此产生的正则: lpat= 'img
src="(http://ac.tc.qq.com/.*?&)amp;(.*?)amp;(dir_path=/&)amp;(.*?.jpg)'
在其中多了三个amp;


首先用1-10进行测试,此时没有问题,在此对图片地址利用正则进行提取,随后用对10-50页进行抓取,因为最开始是利用Charom进行网页动态获取,此时发现部分网页跳转到错误网页‘http://ac.qq.com/ComicView/index/1’,分析之后发现网址并不是按照漫画的话数依次跳转,会出现

‘http://ac.qq.com/ComicView/index/id/622439/cid/13’直接跳转到‘
http://ac.qq.com/ComicView/index/id/622439/cid/16’

这个时候本来想看这个跳转是否有规律,应该是没有的,

(因为昨天第二话是‘http://ac.qq.com/ComicView/index/id/622439/cid/2’
今天却是‘http://ac.qq.com/ComicView/index/id/622439/cid/3?fromPrev=1’)

因此应对错误跳转画面进行分析,找到与正常页面不一样的地方,对其进行过滤,由于动态抓取比较耗费时间,所以过滤前抓取的数去用requests进行获取:



过滤错误网页正则:

        string='(html lang=.*? dir=.*? id=.*?index)'


后对50-100页进行测试,这时发现大部分只获取到一张图片,由此觉得可能是正则出现了问题,找到了出现这个问题的网页,发现该网页存储漫画图片的网址HTML格式确实发生了改变,由此产生另一个正则:

 

       
    lpat='img
src="(http://ac.tc.qq.com/.*?&)amp;(uin.*?&)amp;(dir_path=/&)amp;(name=.*?.ori)'
 在另一个正则获取图片地址少于5的时候启用该正则进行提取,此时的网址依然不是图片真实地池,同样多了3个amp;
后三个模块主要为了实现图片保存以及创建文件夹,
selenium.webdriver安装需要自行查询相关资料,两个代码的主要区别在于后一个不需要打开真实浏览器.
接下来上代码:

chrom
import requests import urllib.request import re import selenium.webdriver
import random import time from PIL import Image from io import BytesIO import
os headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36")
opener=urllib.request.build_opener() opener.addheaders=[headers]
urllib.request.install_opener(opener) def scroll(n,i): return
"window.scrollTo(0,(document.body.scrollHeight/{0})*{1}*30);".\ format(n,i) def
get_ac(url): driver = selenium.webdriver.Chrome() driver.get(url) n=10 for i in
range(0,n+1): s=scroll(n,i) print(s) driver.execute_script(s)
time.sleep(random.randint(1,10)) content=driver.page_source driver.quit()
return content lpat= 'img
src="(http://ac.tc.qq.com/.*?&)amp;(.*?)amp;(dir_path=/&)amp;(.*?.jpg)'
tpat=id='"chapter" title="(.*?)"' mpat='span
class="title-comicHeading">(.*?)</span>' try: for i in range(56,200): url =
'http://ac.qq.com/ComicView/index/id/531490/cid/' + str(i) + '/auth/1?top=0'
data=requests.get(url) string='(html lang=.*? dir=.*? id=.*?index)'
response=data.text #print(response) ft=re.compile(string).findall(response)
print(ft) if ft ==[]: content=get_ac(url)
lqurl=re.compile(lpat).findall(content) tqurl =
re.compile(tpat).findall(content) mqurl = re.compile(mpat).findall(content)
print(tqurl[0]) print(len(tqurl)) print(mqurl[0]) print(len(mqurl))
print(lqurl) print(content) #f=open('filename','wb') if len(lqurl)<5: lpat='img
src="(http://ac.tc.qq.com/.*?&)amp;(uin.*?&)amp;(dir_path=/&)amp;(name=.*?.ori)'
lqurl = re.compile(lpat).findall(content) print(lpat) for j in
range(0,len(lqurl)): if len(lqurl) < 5: f = open('E:/python云沉/img/error.txt',
'a') f.write('第' + i + '话爬取出错') f.close() tqurl[0] = tqurl[0] + 'error'
print('第' + i + '话爬取出错') #continue
filename='E:/python云沉/img/'+str(tqurl[0])+'/'+str(mqurl[0])+'/'
isExists=os.path.exists(filename) if not isExists: os.makedirs(filename)
print(filename+'创建成功')
filename2='E:/python云沉/img/'+str(tqurl[0])+'/'+str(mqurl[0])+'/'+str(j)+'.jpg'
lq=list(lqurl[j]) s=lq[0]+lq[1]+lq[2]+lq[3] response= requests.get(s)
img=Image.open(BytesIO(response.content)) img.save(filename2) #f.write(img)
#urllib.request.urlretrieve(lqurl[i], filename=filename) pass else: continue
#print(content) print(len(lqurl)) except OSError as e: print(e).PhantomJSimport
requests import urllib.request import re import selenium.webdriver import
random import time from PIL import Image from io import BytesIO import os
headers = ("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko)" " Chrome/65.0.3325.146 Safari/537.36")
opener = urllib.request.build_opener() opener.addheaders = [headers]
urllib.request.install_opener(opener) def scroll(n,i): return
"window.scrollTo(0,(document.body.scrollHeight/{0})*{1}*30);".\ format(n,i) def
get_ac(url): driver = selenium.webdriver.PhantomJS()
driver.set_page_load_timeout(30) driver.get(url) n=10 for i in range(0,n+1):
s=scroll(n,i) print(s) driver.execute_script(s)
time.sleep(random.randint(1,10)) content=driver.page_source driver.quit()
return content lpat= 'img
src="(http://ac.tc.qq.com/.*?&)amp;(.*?)amp;(dir_path=/&)amp;(.*?.jpg)'
tpat=id='"chapter" title="(.*?)"' mpat='span
class="title-comicHeading">(.*?)</span>' try: for i in range(1, 10): url =
'http://ac.qq.com/ComicView/index/id/626901/cid/' + str(i) + '/auth/1?top=0'
data = requests.get(url) string = '(html lang=.*? dir=.*? id=.*?index)' #
string=urllib.request.quote(string) # print(string) response = data.text #
print(response) ft = re.compile(string).findall(response) print(ft) if ft==[]:
content = get_ac(url) lqurl = re.compile(lpat).findall(content) tqurl =
re.compile(tpat).findall(content) mqurl = re.compile(mpat).findall(content) if
len(lqurl) < 5: lpat = 'img
src="(http://ac.tc.qq.com/.*?&)amp;(uin.*?&)amp;(dir_path=/&)' \
'amp;(name=.*?.ori)' lqurl = re.compile(lpat).findall(content) print(lpat) for
j in range(0, len(lqurl)): if len(lqurl) < 5:
f=open('E:/python云沉/img/error.txt','ab') f.write('第'+str(i)+'话爬取出错')
f.write(content) f.close() tqurl[0] = tqurl[0] + 'error'
print('第'+str(i)+'话爬取出错') filename = 'E:/python云沉/img/' + str(tqurl[0]) + '/' +
str(mqurl[0]) + '/' isExists = os.path.exists(filename) if not isExists:
os.makedirs(filename) print(filename + '创建成功') filename2 = 'E:/python云沉/img/' +
str(tqurl[0]) + '/' + str(mqurl[0]) + '/' + str(j) + '.jpg' lq = list(lqurl[j])
s = lq[0] + lq[1] + lq[2] + lq[3] response = requests.get(s) img =
Image.open(BytesIO(response.content)) img.save(filename2) pass else: continue
print(len(lqurl)) except OSError as e1:
最后来个效果图,本代码在博文发出前尚可用,运行环境为Python3.