今日爬取一聽/揚天音樂都遇到了某些問題,現在對爬取過程中遇到的問題,做對於自己而言較為系統的補充與解釋。主要問題有一下幾點:
一:beautiful,urllib等庫進行網頁解析時,對於目標下的東西無法進行解析與顯示
二:正則匹配雖然看過許多,但實際使用時仍然不夠熟練,需要大量參考,故而,打算重新整理
三:對於亂碼問題,曾在建mysql數據庫時,頭疼多次,現打算對於網頁解析的亂碼處理方法做些整理
這次目標是爬取揚天音樂“http://up.mcyt.net/”,需要獲取的內容有:歌曲名,歌手以及打開瀏覽器即可播放的音樂鏈接(格式大致:http://up.mcyt.net/md5/53/******.mp3)
這個任務相對簡單,至少在爬蟲道路上遇到了又一新情形,故在此稍加敘述。
現在需要爬取截圖中的音樂外接,如下圖,以及與之對應的web元素
<label>
<span>音樂外鏈:</span>
<input type="text" name="name" value="http://up.mcyt.net/md5/53/MTcwMzYwMg_Qq4329912.mp3">
<br>
<span>a網頁代碼:</span>
<input type="text" name="name" onlick="select();" value="<object height="0" width="0" data="http://up.mcyt.net/p/37823.html"></object>">
<label>
一開始使用的是常規的BeautifulSoup框架進行解析:
response = urlopen(url)
bsObj = BeautifulSoup(response, "html.parser")
li=bsObj.findAll("input",{"type":"text" ,"name":"name"})li=bsObj.findAll("input", {"type": "text" })
print li
但是返回的結果,無法通過li.attrs['value']獲取需求的字符串。原因:以上思路對應的網站元素的格式是
<a "attr1"=“xxx" “attr2”="xxx" "attr3"="xxxx">text</a>
解決方法:
首先解析到<input "attr1"="xxx" "attr2"="xxx">的上一層的target,然后再采用正則的方法獲取對應的attrs,
def getInfo(html):
reg=r'value="(.+?.mp3)" ' #傳說中的 pattern
mp3=re.compile(reg)
mp3list=re.findall(mp3,html)
return mp3list
現在進入第二部分的整理:正則匹配。
1.Python支持的正則表達式元字符和語法
2.re模塊:使用re的一般步驟是先將正則表達式的字符串形式編譯為Pattern實例,然后使用Pattern實例處理文本並獲得匹配結果(一個Match實例),最后使用Match實例獲得信息,進行其他的操作。
import
re
# 將正則表達式編譯成Pattern對象
pattern
=
re.
compile
(r
'hello'
)
# 使用Pattern匹配文本,獲得匹配結果,無法匹配時將返回None
match
=
pattern.match(
'hello world!'
)
if
match:
# 使用Match獲得分組信息
print
match.group()
### 輸出 ###
# hello
3.本次使用以上 詳細的正則可參考:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html#top 和 相關的拓展:www.cnblogs.com/animalize/p/4949219.html
亂碼問題
1.#coding:utf-8 #.py文件是什么編碼就需要告訴python用什么編碼去讀取這個.py文件。
2.sys.stdout.encoding,默認就是locale的編碼,print會用sys.stdout.encoding去encode()成字節流,交給terminal顯示。所以locale需要與terminal一致,才能正確print打印出中文。
3.sys.setdefaultencoding(‘utf8’),用於指定str.encode() str.decode()的默認編碼,默認是ascii。
~對編碼字符串a,代碼中可以直接寫a.encode(“gbk”),但事實上內部自動先通過defaultencoding 去decode成unicode之后再encode()的。
- ~str(xxx)應該也是用這個去編碼的。
~'ascii' codec can't encode characters in position 7-8: ordinal not in range(128)
print的時候出現這個錯誤一般可以使用這個方案去處理。
- ~為了避免代碼中到處都要去encode(“xxx”),還有可能不同的地方寫得不一樣帶來不一致的情況,推薦使用這個:
import sys reload(sys) sys.setdefaultencoding('utf8')
4.判斷解析的網頁的編碼: