【笔记8】选择性放弃正则式吧

忽发奇想,想把某个网站的个人介绍的照片和对应的名字爬下来,想正则式想了很久都没想出来,大神指点用beautifulsoup吧,挣扎了一段时间我觉得在这个问题上放弃正则式。(还是想要想出来)

问题描述

[li]
	[a][img src="(url)" border="0"][/a]
	[div]
		[p][strong](name)[/strong][/p]
		[p][/p]
		[p][/p]
	[/div]
[/li]

每个人的个人信息存在list里,首先是图片,其次是个人简介,一看特别简单,要爬的信息前后都有明显的标记。
src="(.*?) border"[strong](.*?)[/strong]就能提出来了,但问题是我想让同一个人(同一个List)的信息存在一起,这样取姓名就很方便。
然鹅,我想来想去……想不出来,只能或出来,这并不是我想要的结果。

beautifulsoup

于是转战bs4,首先是安装有点小问题,直接pip install下不下来,只能去官网下安装包,放到python27/Scripts里pip安装。
又然鹅,报错。

'module' object has no attribute '_base'

1.治标不治本的方法,复制C:\Python27\Lib\site-packages\html5lib\treewalkers\base.py改为_base.py放到C:\Python27\Lib\site-packages\bs4\builder里,之后会其他报错……

ImportError: cannot import name '_htmlparser'

这个的解决方案是修改C:\Python27\Lib\site-packages\bs4\builder\__init__.py文件,在文件的末尾,注释掉下面几行:

from . import _htmlparser
register_treebuilders_from(_htmlparser)
try:
    from . import _html5lib
    register_treebuilders_from(_html5lib)
except ImportError:
    # They don't have html5lib installed.
    pass

以上方法,又会出现没有parser的错误,不推荐。

2.根本问题是html5lib的版本过高,只要安装一个低于1.0的就可以解决。
pip install --upgrade html5lib==1.0

最后解决

利用beautifulsoup,很容易就能实现我们的要求。
先将html转换
soup = BeautifulSoup(html, 'html.parser')
里面的结构就会标准化了,直接find_all标签就可以提取一个块,针对每个块(每个memberlist)再提取每个人的头像url和姓名,扩展列表存进去。这样就是每人对应一行,第一列为url,第二列为名字。

for member in soup.find_all('li'):
            img = member.find('img')
            imgre = re.compile('src="(.*)"/')
            imgurl = re.findall(imgre, str(img))

            if len(imgurl) != 0:
                name = member.find('strong')
                namere = re.compile('<strong>(.*?)</strong>')
                nameli = re.findall(namere, str(name))

                memberlist.append([])
                memberlist[i].append(imgurl)
                memberlist[i].append(nameli)
                i += 1
            else:
                pass

其中有两个点需要注意,图片的格式不一定相同,因此需要提取出来,将url按’.'分割,取最后一位的format。此外,在利用urlretrieve()函数存图片时,一直会报错,原因是我们爬的中文编码和存储的编码不一致,导致在open路径时报错,因此要将姓名解码成Unicode(将list转成string后,我们可以用chardet函数查看该字符串的编码)。
参考博客:urllib.urlretrieve(url, file_path) 保存中文名乱码

        x = 0
        for imginfo in memberlist:
            imgformat = ''.join(imginfo[0]).split('.')
            imgformat = ''.join(imgformat[-1])
            imgcompurl = 'http://..../' + ''.join(imginfo[0])

            fencoding = chardet.detect(''.join(imginfo[1]))

            imgsave = ('../images/' + ''.join(imginfo[1]).decode('utf-8')+ '.' + imgformat)
            #urllib.urlretrieve(imgcompurl, imgsave)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章