python爬取图片时忽略了一些图片

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python爬取图片时忽略了一些图片相关的知识,希望对你有一定的参考价值。

想要爬取里面的美女图片,但是结果只有一张旁边的广告。
源代码:
import urllib.request
import os

def url_open(url):
req = urllib.request.Request(url)
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0')
response =urllib.request.urlopen(url)
html = response.read()

print(url)
return html

def get_page(url):
html =url_open(url).decode('utf-8')

a = html.find('current-comment-page') +23
b = html.find(']',a)

return html[a:b]

def find_imgs(url):
html =url_open(url).decode('utf-8')
img_addrs =[]

a = html.find('img src=')

while a!=-1:
b =html.find('.jpg',a,a+255)
if b != -1:
img_addrs.append(html[a+9:b+4])
else:
b = a+9

a = html.find('img src=',b)

for each in img_addrs:
print(each)

return img_addrs

def save_img(floder,img_addrs):
for each in img_addrs:
filename = each.split('/')[-1]
with open(filename,'wb') as f:
img = url_open(each)
f.write()

def download(floder = 'ooxx',pages =10):
os.mkdir(floder)
os.chdir(floder)

url = "http://jandan.net/ooxx/"
page_num = int(get_page(url))

for i in range(pages):
page_num -= i
page_url = url + 'page-' + str(page_num) + '#comments'
img_addrs = find_imgs(page_url)
save_img(floder,img_addrs)

if __name__ == '__main__':
download()

真实图片地址是在客户端javascript代码中计算出来的.

你需要寻找

<span class="img-hash">Ly93dzMuc2luYWltZy5jbi9tdzYwMC8wMDczdExQR2d5MWZ3Z3h6ajlrMGtqMzBpYjBramtnaS5qcGc=</span>

这样的内容,取出

Ly93dzMuc2luYWltZy5jbi9tdzYwMC8wMDczdExQR2d5MWZ3Z3h6ajlrMGtqMzBpYjBramtnaS5qcGc=

这段内容,做base64解码即得图片地址。

相应的脚本在

//cdn.jandan.net/static/min/91798e4c623fa60181a31d543488217eB2GDr79r.03100001.js

这段内容你通过get_page()爬到地页面中有,同样,该页面中有这样的html(为便于阅读已重排格式):

<div class="text">
  <span class="righttext">
    <a href="//jandan.net/ooxx/page-34#comment-4001800">4001800</a>
  </span>
  <p>
    <img src="//img.jandan.net/img/blank.gif" onload="jandan_load_img(this)" />
    <span class="img-hash">Ly93dzMuc2luYWltZy5jbi9tdzYwMC8wMDczdExQR2d5MWZ3Z3h6ajlrMGtqMzBpYjBramtnaS5qcGc=</span>
  </p>
</div>

这个img的onload调用的函数就在前面给出的那个js文件中:

function jandan_load_img(b)
  var d=$(b);
  var f=d.next("span.img-hash");
  var e=f.text();
  f.remove();
  var c=jdDw3Ldvi4NcbKboi4X19hCAmdC3Q3aZvN(e,"DGmLfT4H73yJdXXpXs3pw7uAiICcflZS");
  var a=$('<a href="'+c.replace(/(\\/\\/\\w+\\.sinaimg\\.cn\\/)(\\w+)(\\/.+\\.(gif|jpg|jpeg))/,"$1large$3")+
          '" target="_blank" class="view_img_link">[查看原图]</a>');
  d.before(a);
  d.before("<br>");
  d.removeAttr("onload");
  d.attr("src",location.protocol+c.replace(/(\\/\\/\\w+\\.sinaimg\\.cn\\/)(\\w+)(\\/.+\\.gif)/,"$1thumb180$3"));
  if(/\\.gif$/.test(c))
    d.attr("org_src",location.protocol+c);
    b.onload=function()
      add_img_loading_mask(this,load_sina_gif)
  

它调用了jdDw3Ldvi4NcbKboi4X19hCAmdC3Q3aZvN对img-hash的内容做解码,这个函数同样在这个js文件中:

var jdDw3Ldvi4NcbKboi4X19hCAmdC3Q3aZvN=function(o,y,g)
  var d=o;var l="DECODE";
  var y=y?y:"";
  var g=g?g:0;
  var h=4;
  y=md5(y);
  var x=md5(y.substr(0,16));
  var v=md5(y.substr(16,16));
  ...中间部分略去...
  if(l=="DECODE")
    m=base64_encode(m);
    var c=new RegExp("=","g");
    m=m.replace(c,"");
    m=u+m;
    m=base64_decode(d)
  
return m
;

你只需要在Python使用相应的库对抓取到的img-hash内容做解码即可得到图片地址。

你使用了str的find来从文本中定位位置,这样做太麻烦了,太多的代码细节,使用re模块做正则匹配就简单很多,更快的是直接使用现有的爬虫库.

使用re进行正则匹配,只需要使用正则式'<span class="img-hash">(.+?)<'即可提取出该页面中所有加密的图片地址。

import re
import base64
pat = re.compile('<span class="img-hash">(.+?)<')
...
def get_imgurls(url):
    urls = []
    for imgurl in pat.findall(url_open(url).decode('utf-8')):
        .append(str(base64.b64decode(imgurl), 'utf-8'))
    return urls

然后就可以对get_imgurls返回的列表遍历,逐个交给save_img处理了。

使用爬取库也只需要寻找span,从中找出class='img-hash'即可读取text。

参考技术A 有没有水印是得用图形学的方法去判断的,或者人工判断

以上是关于python爬取图片时忽略了一些图片的主要内容,如果未能解决你的问题,请参考以下文章

python多线程爬取图片实例

python爬取MM图片

超详细Python-一键爬取图片音频视频资源

python网络爬虫之爬取图片

Python 爬取美女图片,分目录多级存储

爬取一些网页图片