本来是准备爬取相亲网站的信息为广大单身青年做贡献的,但是注册虚假信息不太好,所以还是来爬取教程上的网站。
在装好python环境以及插件的情况下,在dos命令窗口输入“jupyter notebook" 命令,默认浏览器上会弹出如下窗口 :
选择 "New" 下的 "Python3" 选项,就会弹出一个新的编辑页面,接着就可以开始爬取图片信息了。
这次爬取的网站的URL为 : http://jandan.net/
第一页图片的URL为 : http://jandan.net/ooxx/page-1
第二页图片的URL为 : http://jandan.net/ooxx/page-2
类推最后一页图片的URL为 : http://jandan.net/ooxx/page-87
在每次访问http://jandan.net/ooxx/时,页面会自动锁定在最后一页,所以可以直接抓取这个页面的信息来获得网站类似页面的最大页数。首先来抓取网页的源码 :
添加headers是为模拟网页登陆,避免一些反爬虫网站的拒绝请求,print(res.text)为打印网页源码(测试是否抓取到网页,后期删除),代码编辑完成后,点击shift + enter即可看到网页源码
返回需要抓取信息的网站,按F12进入开发者模式,找到最后一页87所在的标签
然后从span标签下抓取当前时间的最大页数 :
注 : 在获取最大页面的时候,代码获取到的数字带有 "[]" ,所以需要用切片来获取数字
得到最大的页面数后,开始循环所有页面
循环页面后,开始抓取各个页面的图片。首先在原网页的开发者模式下找到图片的标签 :
然后开始提取img的信息,通过img下的信息来访问图片 :
但是运行后的结果显示 :
提取到的图片src已被加密,如果要获取图片的src则首先要将这个奇葩解密。解密需要请求页面获得两个信息,一个是每张图片的hash值,这个用于之后解密生成图片的信息,另一个是提取关键JS文件的地址,每张图片的JS地址是不同的,所以需要从页面中提取,得到了hash和JS的关键参数后,可以根据JS提供的解密方式得到图片链接(膜拜大神的解密方法 : )
def _md5(value):
'''md5加密'''
m = hashlib.md5()
m.update(value.encode('utf-8'))
return m.hexdigest()
def _base64_decode(data):
'''bash64解码,要注意原字符串长度报错问题'''
missing_padding = 4 - len(data) % 4
if missing_padding:
data += '=' * missing_padding
return base64.b64decode(data)
def get_imgurl(m, r='', d=0):
'''解密获取图片链接'''
e = "DECODE"
q = 4
r = _md5(r)
o = _md5(r[0:0 + 16])
n = _md5(r[16:16 + 16])
l = m[0:q]
c = o + _md5(o + l)
m = m[q:]
k = _base64_decode(m)
h = list(range(256))
b = [ord(c[g % len(c)]) for g in range(256)]
f = 0
for g in range(0, 256):
f = (f + h[g] + b[g]) % 256
tmp = h[g]
h[g] = h[f]
h[f] = tmp
t = ""
p, f = 0, 0
for g in range(0, len(k)):
p = (p + 1) % 256
f = (f + h[p]) % 256
tmp = h[p]
h[p] = h[f]
h[f] = tmp
t += chr(k[g] ^ (h[(h[p] + h[f]) % 256]))
t = t[26:]
return t
def get_r(js_url):
'''获取关键字符串'''
js = requests.get(js_url).text
_r = re.findall('c=f_[\w\d]+\(e,"(.*?)"\)', js)[0]
return _r
def get_urls(url):
'''获取一个页面的所有图片的链接'''
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0',
'Host': 'jandan.net'
}
html = requests.get(url, headers=headers).text
js_url = 'http:' + re.findall('<script src="(//cdn.jandan.net/static/min/[\w\d]+\.\d+\.js)"></script>', html)[-1]
_r = get_r(js_url)
soup = BeautifulSoup(html, 'lxml')
tags = soup.select('.img-hash')
for tag in tags:
img_hash = tag.text
img_url = get_imgurl(img_hash,_r)
print(img_url)
if __name__ == '__main__':
get_urls('http://jandan.net/ooxx/page-44')
将图片解密后可以提取图片的地址 :
图片的地址提取完成后,在地址的最前面加上“http:" ,在万维网中,指向某一图片的地址是唯一的,所以只需获取图片地址以及图片的二进制数据就可以访问图片了。最后将图片保存在本地即可。
imgs = requests.get(img_url,headers=headers)
filename = img_url.split('/')[-1]
with open(filename, 'wb') as f:
# 直接过滤掉保存失败的图片
try:
f.write(imgs.content)
print('Sucessful image:',filename)
except:
print('Failed:',filename)
def mkdir(path):
isExists = os.path.exists(os.path.join("F:\jiandan", path))
if not isExists:
print('makedir', path)
os.makedirs(os.path.join("F:\jiandan", path))
os.chdir(os.path.join("F:\jiandan", path))
return True
else:
print(path, 'already exists')
return False
完成爬取。