1. 程式人生 > >【python學習筆記】用正則表示式從含中文的網頁中提取資料(含編碼轉換)

【python學習筆記】用正則表示式從含中文的網頁中提取資料(含編碼轉換)

目標:用正則表示式從含中文的網頁中提取資料

1、獲得網頁全部資料

1.1思考過程

確定我們要操作的網頁:url = 'http://q.stock.sohu.com/cn/603077/cwzb.shtml'
開啟要操作的網頁:req = urllib2.open(url)
讀取網頁,並將網頁資料放入變數:html = req.read()
別忘了把網頁關了:req.close()

1.2把以上過程寫成函式:

def get_html(url):
	try:
		req = urllib2.open(url)
		html = req.read()
		return html
	finally:
		req.close()
html = get_html('http://q.stock.sohu.com/cn/603077/cwzb.shtml')


2、檢視網頁

2.1思考過程

因為不用會開發工具直接檢視網頁原始碼,順便為練習I/O,因此,打算把網頁輸出到TXT。
開啟可寫檔案:file = open('C:/Users/YourName/Desktop/text.txt','w')
將網頁資料寫入檔案:file.write(html)
別忘了把檔案關了:file.close()

2.2把以上過程寫成函式:

def out_put(file_name,content):
	try:
		file = open(file_name,'w')
		file.write(content)
	finally:
		file.close()


out_put('C:/Users/YourName/Desktop/text.txt',html)

執行後,在桌面的text檔案裡檢視網頁原始碼。

3、分析網頁原始碼

3.1確定網頁編碼

檢視網頁原始碼,一般在head處,會標明編碼型別,本例測試網頁中的編碼型別為:gb2312
有些網頁head處標明的編碼型別與實際不符,很沒素質,會導致後續程式碼不可用,因此,有第三方py包chardet用於測試str編碼型別(本人未下載,不會用)。

3.2確定擬抓取資料

想抓取“利潤總額”的數值和百分比,檢視原始碼,“利潤總額”附近程式碼如下:
……


</td>


</tr>


<tr class="e4">


<th>利潤總額</th>


<td>


19392


</td>


<td>


<span class=green>-72.22%</span>


</td>
……

3.3正則表示式

表示式中有中文,別忘加"u";任何時候,別忘加"r"
expression = ur'利潤總額\D+?(-?\d+\.?\d*)\D*?(-?\d+.*?%)'


3.4一件很嚴肅的事!!!

由於此處有非中文字元,因此,“格式”中須選擇“以utf-8格式編碼”,不能選“無BOM”,否則執行就報錯,原因不明。

4、提取資料

pattern = re.compile(expression)
result = pattern.findall(html)


另一件很嚴肅的事!!!
以此程式碼執行,正則啥也匹配出來,原因在於網頁html的編碼為gb2312,而程式程式碼為unicode編碼,兩者不統一,遇到中文匹配不上,需把兩者統一,即修改程式碼:
pattern = re.compile(expression.encode('gb2312'))	#把程式程式碼編碼轉換成'gb2312'


注:程式碼轉換參考http://xanderzhang.iteye.com/blog/465992

5、整合

# -*- coding : utf-8 -*-
import urllib2
import re
def get_html(url):
	try:
		req = urllib2.urlopen(url)
		html = req.read()
		return html
	finally:
		req.close()
html = get_html('http://q.stock.sohu.com/cn/603077/cwzb.shtml')
expression = ur'利潤總額\D+?(-?\d+\.?\d*)\D*?(-?\d+.*?%)'
pattern = re.compile(expression.encode('gb2312'))
result = pattern.findall(html)
print result

關於Unicode編碼問題,參考一篇很詳細的文章:http://blog.csdn.net/dao123mao/article/details/5396497