網頁爬蟲(超超簡單的一個小例子)

(一) 目標:
  在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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章