前一阵心血来潮想爬害羞组的图片,虽然并没有爬虫的经验,但听说并不是很难的事情,就抽时间搞了一下。虽然达到了慕白哦,但只能粗暴的获取,没有间隔访问和异常处理等功能。但总归是自己辛苦搞出来的,遂记录在此。代码在最后
实现过程
方法参考
网上查到了花瓣图片的爬取代码,试验后以此为基础进行豆瓣小组代码的编写。
分析
爬取图片其实就是获得图片的地址,有了一系列的地址对应下载就可以了。因此,就要分析出一个页面里怎样获得图片地址,它有哪些特殊的地方可以与其他内容区分开来。 原帖中花瓣的图片信息在一个格式化的字符串里,但豆瓣小组显然不是。
它是用户发帖,每一页的图片数量不定。
加载不同的帖子提取图片
加载不同的页面提取帖子
最后,决定采用最直接的方法,正则匹配。
- 匹配帖子连接:每一个发帖链接末尾都是数字,且都会有一个title属性,所以用正则
href="(\S+\d\/)"\s?title
来匹配 - 匹配图片地址:用户发帖含有图片的内容会在一个具有‘topic-figure’类的div里,同时要匹配所有内容防止范围过大,限制长度50
topic-figure[\s\S]{0,50}(https[\s\S]{0,200}jpg)
;
爬虫编写
基本上参考了原帖内容
- 提取帖子地址
根据传递进来的页码,获取所有发帖的地址存入列表。
def load_pages(self,num=1): |
获取图片信息
def get_image_info(self):
""" 得到图片信息 """
pages = self.pageUrls
if pages == []:
return None
for i in range(0,len(pages)):
self.__process_data(self.__load_singlePage(pages[i]))
print "提取第{}条记录".format(i)
return self.images
def __process_data(self, htmlPage):
""" 从html页面中提取图片信息 """
#print "====================="
pat = re.compile(r'topic-figure[\s\S]{0,50}(https[\s\S]{0,200}jpg)')
imgs = pat.findall(htmlPage)
if imgs == []:
return None
for i in range(0,len(imgs)):
info = {}
try:
info['id'] = re.search('p\d{8}.*',imgs[i]).group()
info['url'] = imgs[i]
self.images.append(info)
except :
print 'img error'
def __load_singlePage(self,pageUrl):
""" 加载页面 """
return requests.get(url = pageUrl).content保存图片
def down_images(self):
""" 下载图片 """
print "{} image will be download".format(len(self.images))
for key, image in enumerate(self.images):
print 'download {0} ...'.format(key)
try:
req = requests.get(image["url"])
except :
print 'error'
imageName = os.path.join("./db_hxz_images", image["id"])
self.__save_image(imageName, req.content)
def __save_image(self, imageName, content):
""" 保存图片 """
with open(imageName, 'wb') as fp:
fp.write(content)
问题记录
(1) 正则匹配
(.*)
可以匹配所有字符但不包括换行符([\s\S*])
可以匹配所有字符(包括html中的换行)[\s\S]{0,50}
因为会匹配所有字符,如果不能保证后面的独一无二,一定要加数量限制。
(2) python基础
因为对python不是很熟悉,许多简单的地方碰到麻烦。
列表的连接
L1.extend(L2)
slice切片,
L1[len(L1):len(L1)] = L2
(其中冒号前后代表插入位置)
list.append(obj)
末尾添加对象