网页爬虫(超超简单的一个小例子)

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

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