(一) 目標:
在Uniprot中查詢一系列基因編號(如圖中第二列gene)對應的詳細信息,基因編號以csv格式存儲,輸出的詳細信息也存入csv中
(二) 思路:
查詢了幾個基因編號之後發現,網頁的排版不會變化,唯一改變的是其具體內容,所以決定首先獲取網頁所有的內容,然後進行分析,從中提取出自己想要的信息
(三) 工具:
基於python3,BeautifulSoup,用pandas來讀寫csv
需要的庫:urllib bs4 pandas
注意:python3和python2的urllib不一樣,python2中爲urllib2
(四) 具體步驟:
A. 導入相關庫:
import urllib.request
from bs4 import BeautifulSoup
import csv
import pandas as pd
B. 用pandas讀入csv:
csvFile = 'index.csv'
data = pd.read_csv(csvFile)
*讀入的data是一個字典
C. 獲取網頁信息:
由於要查詢一系列的基因號,例如:B0024.14,F38E9.2,且通過觀察網址可知,基因號的變化只是修改了網址http://www.uniprot.org/uniprot/?query=B0024.14&sort=score中對應的‘query’,如查詢B0024.14時,query= B0024.14,所以每次只需修改網址對應部分即可。這步通過for來實現:
for geneName in data['gene']:
anaUrl = 'http://www.uniprot.org/uniprot/?query=' + geneName + '&sort=score'
page = urllib.request.urlopen(anaUrl)#請求響應網址
contents = page.read()#讀取網址的內容
soup = BeautifulSoup(contents, "html.parser")#對獲得的內容進行解析以便於後續分析
D. 內容分析:
網頁內容都存於soup中,想要獲得相應的內容,需要先對某一個查詢結果網頁的源代碼進行分析,觀察自己想要的信息存在什麼樣的標籤之下。首先點擊鼠標右鍵→‘檢查’查看源代碼,然後按‘Ctrl+Shif+C’,將鼠標放在網頁中的相應位置,代碼的elements中即會跳轉至相應的位置,如將鼠標放在圖中的“supporting data”,右邊顯示該內容存在<div class id="supporting-data-browse"><h3>Supporting data</h3></div>。
此步分析只要找到了相應的位置就可以提取出數值,我用得比較多的命令是“.find_all”,如soup.find_all(‘div’,class_=’content results)
,其中div爲標籤的名稱,class_是類(注意此處的class,在網頁中沒有下劃線,但在python中必須加入,網上看到的解釋是python中class是關鍵字,避免衝突,使用下劃線)。
針對我的目標,觀察發現內容都存在content results下的tbody中,所以實現如下:
for tag in soup.find_all('div', class_='content results'):
m_body = tag.find('tbody')
if m_body is None:
print('None')
else:
en = m_body.find_all("a")#尋找body中的所有a標籤
entry = en[0].text
organism = en[1].text
enn = m_body.find_all("td")#
entryName = enn[2].text
protein = tag.find('div', class_="protein_names")#精確定位
kk = protein.find_all('div', class_="short")
proteinName = kk[0].text
其中,en爲列表,所以直接輸出每一項的內容即可,protein不是最終的結果,還有下層,所以可以再使用find_all,直到最後一層。在html中,可能有很多相同的標籤,所以有些內容提示找不到時,就先尋找此標籤的上級標籤,應該就可以找到。
E. 結果存儲:
可將結果存入一個列表中,然後調用
with open(resultFile, 'a', newline='') as out:
csv_write = csv.writer(out, dialect='excel')
csv_write.writerow(label)
csv_write.writerow(result)
這裏採取’a’是追加csv形式,會在原內容下方新增內容,不會覆蓋原內容。更多的格式可參考http://www.runoob.com/python/python-func-open.html。
其中label爲csv的標題,只需調用一次即可,如label=[‘name’,’entry’,’proteinName’],對應的result爲[‘b0024 14’, ‘G5EF34’,’ CRiM (Cysteine Rich motor neuron protein) homolog’]。
注意:*
find_all 返回包含目標值的一個列表,當對象爲空時,返回空列表;find_all之後不能再用find_all
find 直接返回目標值,當對象爲空時,返回None