抓取动态网页(有些网页就是动态网页的图片元素是怎么自动形成的)

优采云 发布时间: 2021-10-01 03:26

  抓取动态网页(有些网页就是动态网页的图片元素是怎么自动形成的)

  好的,上次我们讲了如何抓取豆瓣美子和暴走*敏*感*词*页面的图片,但是这些页面都是静态页面,几行代码就可以解决问题,因为图片的src在页面(具体来说,失控的*敏*感*词*和尴尬的百科全书如何自动形成一个静态页面是要讨论的)。静态页面的优点是加载速度非常快。

  然而,并不是所有的网页抓取都那么简单。有些网页是动态网页,也就是说页面中的图片元素是由js生成的。原来的html没有图片的src信息,所以希望Python可以模拟浏览器加载js,执行js后返回页面,这样就可以看到src信息了。我们知道图片在哪,不能下载到本地吗(其实如果有链接你可能抓不到,后面再讲)。

  有些网站为了防止别人获取图片,或者说是知识产权,有很多方法,比如*敏*感*词*网站、爱*敏*感*词*和腾讯*敏*感*词*,前者是动态网页生成的图片我说,所以当你打开一个有*敏*感*词*的页面时,图片加载会很慢,因为它是由js生成的(毕竟它不会让你轻易抓取它)。后者比较棘手,或者如果你想捕捉Flash加载的图像,你需要Python来模拟Flash。以后再研究这部分。

  那么上面说的,即使我已经实现了Python用js加载页面并获取了图片元素的src,在访问src的时候,也会说404,比如这个链接。这是爱情*敏*感*词*的全职猎人之一。在*敏*感*词*页面上,当我使用浏览的F12功能时,找到了图片的src属性。当我将链接复制到浏览器时,他告诉我一个 404 错误。该页面不存在。是什么原因?显然是这个地址。啊,而且多次刷新的页面地址也是一样的(别告诉我你能看到这张图,是浏览器缓存的原因,你可以尝试清除缓存,骚年)?那是因为,如果你捕捉网页加载,你会发现获取页面图片的Get请求有以下信息:

  GET /Files/Images/76/59262/imanhua_001.jpgHTTP/1.1

  接受 image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5

  推荐人

  接受语言 zh-CN

  用户代理 Mozilla/5.0(WindowsNT6.1;WOW64;Trident/7.0;rv:11.0)likeGecko

  接受编码 gzip,放气

  主持人

  连接保持活动

  在这里,你只需要模拟他的Get请求来获取图片,因为网站过滤了Get,只有你自己的请求网站才会返回图片,所以我们要在request中添加以上信息在header中,经过测试,只需要添加Referer

  信息会做。URL 是当前网页的 URL。

  我们已经说明了具体实现的原理,接下来看看用的是什么包:

  1.BeautifulSoup包用于根据URL获取静态页面中的元素信息。我们用它来获取爱*敏*感*词*网站中某部*敏*感*词*的所有章节的url,并根据章节的url获取该章节的总页数,并获取每个页面的url,参考材料

  2.Ghost包,用于根据每个页面的url动态加载js,加载后获取页面代码,获取image标签的src属性,Ghost官网,参考资料

  3.urllib2包,模拟Get请求,使用add_header添加Referer参数获取返回图片

  4.chardet 包,解决页面乱码问题

  我们依次以以上四个步骤为例,或者以抢爱*敏*感*词*网站的*敏*感*词*为例:

  1. 输入*敏*感*词*号,通过BeautifulSoup获取所有章节和章节下的子页面url

  2. 根据第一步动态获取的页面url,使用Ghost动态加载页面,传入url获取页面图片的src

  #通过Ghost模拟js获取动态网页生成的图片src

class FetcherCartoon:

def getCartoonUrl(self,url):

if url is None:

return false

#todo many decide about url

try:

ghost = Ghost()

#open webkit

ghost.open(url)

#exceute javascript and get what you want

page, resources = ghost.wait_for_page_loaded()

result, resources = ghost.evaluate("document.getElementById('comic').getAttribute('src');", expect_loading=True)

del resources

except Exception,e:

print e

return None

return result

  3.urllib2 模拟Get请求并写入图片

  #传入url模拟Get请求,获取图片内容

def GetImageContent(wholeurl,imgurl):

time.sleep(0.1)

req = urllib2.Request(imgurl)

req.add_header('Referer', wholeurl)

content = urllib2.urlopen(req).read()

rstr = r"[\/\\\:\*\?\"\\|]" # '/\:*?"|'

new_title = re.sub(rstr, "", str(imgurl)[-20:])

with open(cartoonName+'/'+new_title,'wb') as code:

code.write(content)

  4.chardet 解决乱码问题

  #解决乱码问题

html_1 = urllib2.urlopen(basicURL,timeout=120).read()

mychar = chardet.detect(html_1)

bianma = mychar['encoding']

if bianma == 'utf-8' or bianma == 'UTF-8':

html = html_1

else :

html = html_1.decode('gb2312','ignore').encode('utf-8')

  整体代码如下:

<p># -*- coding:utf8 -*-

import urllib2,re,os,time

import chardet

import cookielib,httplib,urllib

from bs4 import BeautifulSoup

from ghost import Ghost

webURL = &#39;http://www.imanhua.com/&#39;

cartoonNum = raw_input("请输入*敏*感*词*编号:")

basicURL = webURL + u&#39;comic/&#39; + cartoonNum

#通过Ghost模拟js获取动态网页生成的图片src

class FetcherCartoon:

def getCartoonUrl(self,url):

if url is None:

return false

#todo many decide about url

try:

ghost = Ghost()

#open webkit

ghost.open(url)

#exceute javascript and get what you want

page, resources = ghost.wait_for_page_loaded()

result, resources = ghost.evaluate("document.getElementById(&#39;comic&#39;).getAttribute(&#39;src&#39;);", expect_loading=True)

del resources

except Exception,e:

print e

return None

return result

#解决乱码问题

html_1 = urllib2.urlopen(basicURL,timeout=120).read()

mychar = chardet.detect(html_1)

bianma = mychar[&#39;encoding&#39;]

if bianma == &#39;utf-8&#39; or bianma == &#39;UTF-8&#39;:

html = html_1

else :

html = html_1.decode(&#39;gb2312&#39;,&#39;ignore&#39;).encode(&#39;utf-8&#39;)

#获取*敏*感*词*名称

soup = BeautifulSoup(html)

cartoonName = soup.find(&#39;div&#39;,class_=&#39;share&#39;).find_next_sibling(&#39;h1&#39;).get_text()

print u&#39;正在下载*敏*感*词*: &#39; + cartoonName

#传入url模拟Get请求,获取图片内容

def GetImageContent(wholeurl,imgurl):

#time.sleep(0.1)

req = urllib2.Request(imgurl)

req.add_header(&#39;Referer&#39;, wholeurl)

content = urllib2.urlopen(req).read()

rstr = r"[\/\\\:\*\?\"\\|]" # &#39;/\:*?"|&#39;

new_title = re.sub(rstr, "", str(imgurl)[-20:])

with open(cartoonName+&#39;/&#39;+new_title,&#39;wb&#39;) as code:

code.write(content)

#创建文件夹

path = os.getcwd() # 获取此脚本所在目录

new_path = os.path.join(path,cartoonName)

if not os.path.isdir(new_path):

os.mkdir(new_path)

#解析所有章节的URL

chapterURLList = []

chapterLI_all = soup.find(&#39;ul&#39;,id = &#39;subBookList&#39;).find_all(&#39;a&#39;)

for chapterLI in chapterLI_all:

chapterURLList.append(chapterLI.get(&#39;href&#39;))

#print chapterLI.get(&#39;href&#39;)

#遍历章节的URL

for chapterURL in chapterURLList:

chapter_soup = BeautifulSoup(urllib2.urlopen(webURL+str(chapterURL),timeout=120).read())

chapterName = chapter_soup.find(&#39;div&#39;,id = &#39;title&#39;).find(&#39;h2&#39;).get_text()

print u&#39;正在下载章节: &#39; + chapterName

#根据最下行的最大页数获取总页数

allChapterPage = chapter_soup.find(&#39;strong&#39;,id = &#39;pageCurrent&#39;).find_next_sibling(&#39;strong&#39;).get_text()

print allChapterPage

#然后遍历所有页,组合成url,保存图片

currentPage = 1

fetcher = FetcherCartoon()

uurrll = str(webURL+str(chapterURL))

imgurl = fetcher.getCartoonUrl(uurrll)

if imgurl is not None:

while currentPage

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线