本群面相web开发爱好者以及同行,共同探讨研究技术,分享交流经验,帮助新人成长,大牛技术精进,js发展日新月异闭门造车是没有出路的,有问必答,共同进步。求职招聘qq群 626448857
爬取两百张效果图:测试花瓣网站
[http://huaban.com/favorite/beauty/](http://huaban.com/favorite/beauty/)
思路:在这个页面中<script 标签下有一行以 app.page[“pins”] 开头的,就是我们要找的部分,等号后面是一个json字符串。每张要找的图片对应一个字典,图片的url地址与"file"下的"key"有关,图片类型与"file"下的"type"有关,只要得到这两个值就可以下载到图片了。
在每次下拉刷新时,也是发送了一个get请求,在这个请求中有一个关键参数max,这个就是当前页面中最后一个图片的"pin_id",所以,需要抓取三个内容,分别是"pin_id",“file”.“key"和"file”.“type”。
打印主页请求的内容下图:
打印通过循环提取后的数据(url ,tpye ,id):
# encoding: utf-8
import requests
import re
import os
import os.path
class HuabanCrawler():
""" 抓取花瓣网上的图片 """
def __init__(self):
""" 在当前文件夹下新建images文件夹存放抓取的图片 """
self.homeUrl = "http://huaban.com/favorite/beauty/"
self.images = []
if not os.path.exists('./images'):#判断不存在当前目录不存在images文件夹时创建
os.mkdir('./images')
def __load_homePage(self):
""" 加载主页面 """
return requests.get(url = self.homeUrl).content
def __load_more(self, maxNo):
""" 刷新页面 """
#把拼接的请求路径与request请求写在一个方法里
return requests.get(url = self.homeUrl + "?i5p998kw&max=" + maxNo + "&limit=20&wfl=1").content
def __process_data(self, htmlPage):
""" 从html页面中提取图片的信息 """
prog = re.compile(r'app\.page\["pins"\].*')#正则取出需要的数据 \ 转义
appPins = prog.findall(htmlPage)#返回列表
# 将js中的null定义为Python中的None
null = None
true = True
if appPins == []:
return None
result = eval(appPins[0][19:-1])#返回表达式的值,将截取结果str转为list用于循环
for i in result: #循环取出需要的数据
info = {}
info['id'] = str(i['pin_id'])
info['url'] = "http://img.hb.aicdn.com/" + i["file"]["key"] + "_fw658"
if 'image' == i["file"]["type"][:5]:
info['type'] = i["file"]["type"][6:] #截取列表中图片后缀
else:
info['type'] = 'NoName'
self.images.append(info)#往images列表中添加数据
def get_image_info(self, num=20):
""" 得到图片信息 """
self.__process_data(self.__load_homePage())#返回图片信息列表,主页请求的20条数据
# print self.images
# 从 0 开始到 9
for i in range((num-1)/20):#创建一个整数列表,用请求总数除以每次请求20,等于一共循环的次数,也就是ajax请求的次数9次,
self.__process_data(self.__load_more(self.images[-1]['id']))#读取列表中倒数第一个元素id19,判断ajax请求
""" 下载图片 """
print "{} image will be download".format(len(self.images))
for key, image in enumerate(self.images): # enumerate(枚举) 对象 0,1,2,3,4,,,,,,,
print 'download {0} ...'.format(key) # 字符串格式化
try:
req = requests.get(image["url"]) # 用requests下载每张图片
except:
print 'error'
imageName = os.path.join("./images", image["id"] + "." + image["type"]) # 将目录和文件名合成一个路径
# 把写入放在循环里执行
with open(imageName, 'wb') as fp: # 图片完整的路径与对应图片写入
fp.write(req.content)
if __name__ == '__main__': #直接运行脚本
hc = HuabanCrawler()
hc.get_image_info(200) #测试两百张图片