上一篇博文,我遇到了防止盗链的问题,

防盗链原理
http标准协议中有专门的字段记录referer
一来可以追溯上一个入站地址是什么
二来对于资源文件,可以跟踪到包含显示他的网页地址是什么
因此所有防盗链方法都是基于这个Referer字段

防盗链的作用
在很多地方,如淘宝、拍拍、有啊等C2C网站,发布商品需要对宝贝进行描述,就需要图片存储,而为了使自己辛辛苦苦拍摄的图片不被别人调用,就需要防盗链的功能。
提供防盗链的图片网站很多,如有照片、又拍网、百度相册、QQ相册、网易相册等等,但是既能支持网店外链,又有防盗链功能的网站很少;

在https://www.mzitu.com/ 进入首页后,进入到每个图片集的html页面,找到对应的图片

Python《第一次爬虫遭遇反盗链(下)》_爬虫

我们能得到它的图片地址,但是唯一需要做的就是不断去修改http header里面referer字段。

重点部分代码就是如下:

Python《第一次爬虫遭遇反盗链(下)》_字段_02

每次去请求图片的时候,就把每次更新的、不断变化的header传入即可,就能顺利下载图片了。

具体参考完整代码如下:

import os
import requests
from bs4 import BeautifulSoup

rootrurl = 'https://www.mzitu.com/'
save_dir = 'D:/estimages/'
no_more_pages = 'END'
max_pages = 10

# 这是一个集合,不能重复,也就是不能重复下载图片
image_cache = set()
index = len(image_cache)

headers = {
"Referer": "https://www.mzitu.com/",
'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"
} ###设置请求的头部,伪装成浏览器

def getNextPageUrl(html):
ahref = html.find('a', {'class': 'next page-numbers'}) # 找到导航条的位置,获得下一个连接网页的位置
if ahref is None:
print('no more page')
return no_more_pages
else:
return ahref.get('href')


def findTheNum(navi):
lis = navi.find_all('span')
num = 0
for span in lis:
if span.string.isdigit():
tmp = int(span.string)
if tmp > num:
num = tmp
return num


def deepSaveImgs(href, saveDir):

html = BeautifulSoup(requests.get(href, headers=headers).text, features="html.parser")

# to find the number of max pages
total = findTheNum(html.find('div', {'class': 'pagenavi'}))
print('total of this group is %d.' % total)

for i in range(1, (total+1)):
url = '{}/{}'.format(href, i) # 拼接照片所在html的页面

html = BeautifulSoup(requests.get(url, headers=headers).text, features="html.parser") # 解析每张图片的源码
img_url = html.find('img', attrs={'class': 'blur'}).get('src') # 查找实际每张图片的具体地址

# 因为网站有防盗链,重新设置了头部的Referer ;在浏览器里面F12里打开网络监听,在Request Headers 里面可以看得到
new_headers = {
'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
'Referer': url
}

img = requests.get(img_url, headers=new_headers) # 请求图片的实际URL
print(img.url)
with open(
'{}/{}'.format(saveDir, img.url.split("/")[-1]), 'wb') as jpg: # 请求图片并写进去到本地文件
jpg.write(img.content)
if img.url not in image_cache:
image_cache.add(img.url)


def saveImgs(html, mainidx):
lis = html.find('ul', {'id': 'pins'}).find_all('li')
subidx = 1
for link in lis:
# step 1: save this cover image, and create the folder.
a = link.find('a')
href = a.get('href')
img = a.find('img').get('data-original')
print('封面图片: ' + img)
tag = '{}{}/{}/'.format(save_dir, mainidx, subidx)

if not os.path.exists(tag):
os.makedirs(tag)

with open(
'{}/{}'.format(tag, "coverImg_" + img.split("/")[-1]), 'wb') as jpg: # 请求图片并写进去到本地文件
jpg.write(requests.get(img).content)
if img not in image_cache:
image_cache.add(img)

# step 2: enter the mew page to save deeply.
deepSaveImgs(href, tag) #深度搜索该图片组

subidx = subidx + 1



if __name__ == '__main__':
url = rootrurl
idx = 1
while 1:
print("next page: " + url)
html = BeautifulSoup(requests.get(url, headers=headers).text, features="html.parser")
saveImgs(html, idx) # 处理当前浏览页面

if idx >= max_pages:
break
idx = idx + 1

url = getNextPageUrl(html) # 获得下一个浏览页
if url == no_more_pages:
break

效果挺好的,我再本地也做了二级目录:

同样不能展开了,点到为止。

Python《第一次爬虫遭遇反盗链(下)》_html_03