【筆記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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章