Python技术
知乎上有许多关于颜值、身材的话题,有些话题的回复数甚至高达几百上千,拥有成千上万的关注者与被浏览数。如果我们在摸鱼的时候欣赏这些话题将花费大量的时间,可以用 Python 制作一个下载知乎回答图片的小脚本,将图片下载到本地。


请求 URL 分析
首先打开 F12 控制台面板,看到照片的 URL 都是 https://pic4.zhimg.com/80/xxxx.jpg?source=xxx 这种格式的。


滚动知乎页面向下翻页,找到一个带 limit,offset 参数的 URL 请求。


检查 Response 面板中的内容是否包含了图片的 URL 地址,其中图片地址 URL 存在 data-original 属性中。


提取图片的 URL
从上图可以看出图片的地址存放在 content 属性下的 data-original 属性中。
下面代码将获取图片的地址,并写入文件。
importre
importrequests
importos
importurllib.request
importssl
fromurllib.parseimporturlsplit
fromos.pathimportbasename
importjson
ssl._create_default_https_context=ssl._create_unverified_context
headers={
'User-Agent':"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/89.0.4389.90Safari/537.36",
'Accept-Encoding':'gzip,deflate'
}
defget_image_url(qid,title):
answers_url='https://www.zhihu.com/api/v4/questions/'+str(qid)+'/answers?include=data%5B*%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cattachment%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Cis_labeled%2Cpaid_info%2Cpaid_info_content%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_recognized%3Bdata%5B*%5D.mark_infos%5B*%5D.url%3Bdata%5B*%5D.author.follower_count%2Cbadge%5B*%5D.topics%3Bdata%5B*%5D.settings.table_of_content.enabled&offset={}&limit=10&sort_by=default&platform=desktop'
offset=0
session=requests.Session()
whileTrue:
page=session.get(answers_url.format(offset),headers=headers)
json_text=json.loads(page.text)
answers=json_text['data']
offset+=10
ifnotanswers:
print('获取图片地址完成')
return
pic_re=re.compile('data-original="(.*?)"',re.S)
foranswerinanswers:
tmp_list=[]
pic_urls=re.findall(pic_re,answer['content'])
foriteminpic_urls:
#去掉转移字符
pic_url=item.replace("\","")
pic_url=pic_url.split('?')[0]
#去重复
ifpic_urlnotintmp_list:
tmp_list.append(pic_url)
forpic_urlintmp_list:
ifpic_url.endswith('r.jpg'):
print(pic_url)
write_file(title,pic_url)
defwrite_file(title,pic_url):
file_name=title+'.txt'
f=open(file_name,'a')
f.write(pic_url+'n')
f.close()
示例结果:


下载图片
下面代码将读取文件中的图片地址并下载。
defread_file(title):
file_name=title+'.txt'
pic_urls=[]
#判断文件是否存在
ifnotos.path.exists(file_name):
returnpic_urls
withopen(file_name,'r')asf:
forlineinf:
url=line.replace("n","")
ifurlnotinpic_urls:
pic_urls.append(url)
print("文件中共有{}个不重复的URL".format(len(pic_urls)))
returnpic_urls
defdownload_pic(pic_urls,title):
#创建文件夹
ifnotos.path.exists(title):
os.makedirs(title)
error_pic_urls=[]
success_pic_num=0
repeat_pic_num=0
index=1
forurlinpic_urls:
file_name=os.sep.join((title,basename(urlsplit(url)[2])))
ifos.path.exists(file_name):
print("图片{}已存在".format(file_name))
index+=1
repeat_pic_num+=1
continue
try:
urllib.request.urlretrieve(url,file_name)
success_pic_num+=1
index+=1
print("下载{}完成!({}/{})".format(file_name,index,len(pic_urls)))
except:
print("下载{}失败!({}/{})".format(file_name,index,len(pic_urls)))
error_pic_urls.append(url)
index+=1
continue
print("图片全部下载完毕!(成功:{}/重复:{}/失败:{})".format(success_pic_num,repeat_pic_num,len(error_pic_urls)))
iflen(error_pic_urls)>0:
print('下面打印失败的图片地址')
forerror_urlinerror_pic_urls:
print(error_url)
结语
今天的文章用 Python 爬虫制作了一个小脚本,如果小伙伴们觉得文章有趣且有用,点个 转发 支持一下吧!