python - 用 pandas、beautifulsoup、urllib 抓取:如何检索可能嵌入的字段
问题描述
我知道有这样的问题,我试图跟随他们。我正在尝试抓取此页面中的信息。理想情况下,我希望将尽可能多的信息放入干净/易于阅读的 tsv 中,但要抓取的基本部分是:ID、名称、有机体、家庭、分类、UniProt ID、修改、序列和 PDB 结构 ID(例如在这种情况下,有一个 PDB 结构列表,第一个是 1BAS,最后一个是 4OEG)。
我在python3中写了这个:
import urllib.request
import sys
import pandas as pd
import bs4
out = open('pdb.parsed.txt', 'a')
for i in range(1000,1005):
# try:
url = 'http://isyslab.info/StraPep/show_detail.php?id=BP' + str(i)
page = urllib.request.urlopen(url)
soup = pd.read_html(page)
print(soup)
我有两个问题:
你可以看到我需要的一些信息丢失了(例如序列有 NaN)。
更重要的是,我看不到任何与 PDB ID 列表相关的字段?
如果可能,我希望使用 pd.read_html,因为过去我一直在使用 urllib/bs4,并且我发现在最近的抓取尝试中使用 pd.read_html 更成功。谁能解释我如何提取我需要的字段?
解决方案
我相信您无法从某些行(例如“序列”行)中抓取条目,因为这些行是由 Javascript 填充的。对我有用的方法是结合使用 Selenium 和 Firefox 驱动程序来获取页面的 html 代码,然后使用 Beautiful Soup 来解析该代码。
以下是我如何能够为每个页面的 ID、名称、有机体、家庭、分类、UniProt ID、修改、序列和 PDB 结构 ID 抓取相关信息:
import urllib.request
import sys
import pandas as pd
from bs4 import BeautifulSoup
from selenium import webdriver
import csv
pages = []
for page in range(1000,1005):
# try:
info_dict = {}
url = 'http://isyslab.info/StraPep/show_detail.php?id=BP' + str(page)
driver = webdriver.Firefox()
driver.get(url)
html = driver.page_source
bs = BeautifulSoup(html, 'html.parser')
main_table = bs.find('table', attrs={'class': 'main_table'})
rows = main_table.findAll('tr')
for row in rows:
try: # We only want rows from a page where both row title and text are not null
row_header = row.find('th').text
row_text = row.find('td').text
except:
pass
else:
if row_header and row_text:
if row_header in ['ID', 'Name', 'Organism', 'Family', 'Classification', 'UniProt ID']:
info_dict[row_header] = row_text
elif row_header == 'Modification':
try: # Some pages have a null table entry for 'Modification'
mod_text = row.find('table').find('td').text
except:
pass
else:
if mod_text:
info_dict[row_header] = mod_text
else:
info_dict[row_header] = 'NA'
# Pass 'Sequence' and 'Structure' as space separated strings
elif row_header == 'Sequence':
seqs = ''
for i in row_text.split():
seqs += ' ' + i
info_dict[row_header] = seqs[1:]
elif row_header == 'Structure':
pdb_ids = ''
a = row.find('tbody').find_all('a')
for i in a:
if i.text != '[x]': pdb_ids += ' ' + i.text
info_dict[row_header] = pdb_ids[1:]
pages.append(info_dict)
keys = pages[0].keys()
with open('pdb.parsed.txt', 'a') as output_file:
writer = csv.DictWriter(output_file, keys, delimiter='\t')
writer.writeheader()
writer.writerows(pages) # Add a tab-delimited row for each page we scraped
然后,如果需要,我可以读取刚刚创建为数据框的 .tsv 文件:
df = pd.read_csv('pdb.parsed.txt', delimiter='\t')
尽管包含较长字符串(例如 'Sequence')的列的内容被缩写,但我们可以验证整个序列确实存在:
df.iloc[0]['Sequence']
'PALPEDGGSG AFPPGHFKDP KRLYCKNGGF FLRIHPDGRV DGVREKSDPH IKLQLQAEER GVVSIKGVCA NRYLAMKEDG RLLASKCVTD ECFFFERLES NNYNTYRSRK YTSWYVALKR TGQYKLGSKT GPGQKAILFL PMSAKS'
保存的 tsv 文件的内容如下所示:
ID Name Organism Family Classification UniProt ID Modification Sequence Structure
BP1000 Fibroblast growth factor 2 Homo sapiens heparin-binding growth factors family Cytokine/Growth factor FGF2_HUMAN Phosphotyrosine; by TEC PALPEDGGSG AFPPGHFKDP KRLYCKNGGF FLRIHPDGRV DGVREKSDPH IKLQLQAEER GVVSIKGVCA NRYLAMKEDG RLLASKCVTD ECFFFERLES NNYNTYRSRK YTSWYVALKR TGQYKLGSKT GPGQKAILFL PMSAKS 1BAS 1BFB 1BFC 1BFF 1BFG 1BLA 1BLD 1CVS 1EV2 1FGA 1FQ9 1II4 1IIL 2BFH 2FGF 2M49 4FGF 4OEE 4OEF 4OEG
BP1001 Interleukin-2 Homo sapiens IL-2 family Cytokine/Growth factor IL2_HUMAN APTSSSTKKT QLQLEHLLLD LQMILNGINN YKNPKLTRML TFKFYMPKKA TELKHLQCLE EELKPLEEVL NLAQSKNFHL RPRDLISNIN VIVLELKGSE TTFMCEYADE TATIVEFLNR WITFCQSIIS TLT 1IRL 1M47 1M48 1M49 1M4A 1M4B 1M4C 1NBP 1PW6 1PY2 1QVN 1Z92 2B5I 2ERJ 3INK 3QAZ 3QB1 4NEJ 4NEM
BP1002 Insulin Bos taurus insulin family Hormone INS_BOVIN GIVEQCCASV CSLYQLENYC N 1APH 1BPH 1CPH 1DPH 1PID 2A3G 2BN1 2BN3 2INS 2ZP6 3W14 4BS3 4E7T 4E7U 4E7V 4I5Y 4I5Z 4IDW 4IHN 4M4F 4M4H 4M4I 4M4J 4M4L 4M4M
BP1003 Interleukin-1 beta Homo sapiens IL-1 family Cytokine/Growth factor IL1B_HUMAN APVRSLNCTL RDSQQKSLVM SGPYELKALH LQGQDMEQQV VFSMSFVQGE ESNDKIPVAL GLKEKNLYLS CVLKDDKPTL QLESVDPKNY PKKKMEKRFV FNKIEINNKL EFESAQFPNW YISTSQAENM PVFLGGTKGG QDITDFTMQF VSS 1HIB 1I1B 1IOB 1ITB 1L2H 1S0L 1T4Q 1TOO 1TP0 1TWE 1TWM 21BI 2I1B 2KH2 2NVH 31BI 3LTQ 3O4O 3POK 41BI 4DEP 4G6J 4G6M 4GAF 4GAI 4I1B 5BVP 5I1B 6I1B 7I1B 9ILB
BP1004 Lactoferricin-H Homo sapiens transferrin family Antimicrobial TRFL_HUMAN GRRRSVQWCA VSQPEATKCF QWQRNMRKVR GPPVSCIKRD SPIQCIQA 1Z6V 1XV4 1XV7 1Z6W 2GMC 2GMD
我使用以下 Anaconda 命令安装 Selenium,然后安装 Firefox 驱动程序:
conda install -c conda-forge selenium
conda install -c conda-forge geckodriver
推荐阅读
- sql - 如何避免sql中的`missing expression`错误
- python - 如何在 tkinter 应用程序中获得默认的 Ubuntu 外观
- powerbi - 计算列中的 DAX 分组和排名
- hadoop - 大型 hana 表的 CSV 导出选项会导致内存错误
- algorithm - 为什么当我们将 G 中每条边的成本更改为 c'= log17(c)时,G 中的每个 MST 仍然是 G' 中的 MST(反之亦然)?
- javascript - 如何在 vue js 的内容可编辑 div 中添加组件
- javascript - 建立一个 6 个字母、2 个数字和 1 个标点符号的正则表达式密码
- rust - 我可以从不可变的 BTreeMap 中获取值吗?
- python - 如何使用 Python NLP 从数据库表中提取与搜索字符串中的关键字匹配的关键字
- python - 使用 4-d 内核确定 3-d 卷积的权重维度