python抓取豆瓣小组图片

作者 Zhs 日期 2016-11-08
python抓取豆瓣小组图片

​ 前一阵心血来潮想爬害羞组的图片,虽然并没有爬虫的经验,但听说并不是很难的事情,就抽时间搞了一下。虽然达到了慕白哦,但只能粗暴的获取,没有间隔访问和异常处理等功能。但总归是自己辛苦搞出来的,遂记录在此。代码在最后

实现过程

方法参考

网上查到了花瓣图片的爬取代码,试验后以此为基础进行豆瓣小组代码的编写。

分析

爬取图片其实就是获得图片的地址,有了一系列的地址对应下载就可以了。因此,就要分析出一个页面里怎样获得图片地址,它有哪些特殊的地方可以与其他内容区分开来。 原帖中花瓣的图片信息在一个格式化的字符串里,但豆瓣小组显然不是。

  • 它是用户发帖,每一页的图片数量不定。

  • 加载不同的帖子提取图片

  • 加载不同的页面提取帖子

最后,决定采用最直接的方法,正则匹配。

  • 匹配帖子连接:每一个发帖链接末尾都是数字,且都会有一个title属性,所以用正则href="(\S+\d\/)"\s?title来匹配
  • 匹配图片地址:用户发帖含有图片的内容会在一个具有‘topic-figure’类的div里,同时要匹配所有内容防止范围过大,限制长度50topic-figure[\s\S]{0,50}(https[\s\S]{0,200}jpg);

爬虫编写

基本上参考了原帖内容

  1. 提取帖子地址

根据传递进来的页码,获取所有发帖的地址存入列表。

def load_pages(self,num=1):
""" 从html页面中提取帖子的信息 """
for i in range(0,num):
print "加载第{}页".format(i+1)
self.__save_pages(self.__load_more(i*25))
return self.images
def __save_pages(self, htmlPage):
""" 保存帖子地址 """
prog = re.compile(r'href="(\S+\d\/)"\s?title')
self.pageUrls.extend(prog.findall(htmlPage))
def __make_ajax_url(self, No):
""" ajax加载下一页 """
return self.homeUrl + "?start=" + str(No)
def __load_more(self, maxNo):
""" 获得新页面内容 """
return requests.get(url = self.__make_ajax_url(maxNo)).content
  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
  2. 保存图片

    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) 末尾添加对象

参考 花瓣爬虫
最终代码 github