使用 pandas、beautifulsoup、urllib 进行抓取:如何检索可能嵌入的字段
Scraping with pandas, beautifulsoup, urllib: How to retrieve possibly embedded fields
我知道有这样的问题,我一直在努力跟进。我正在尝试抓取 this 页面中的信息。理想情况下,我希望尽可能多的信息进入 clean/easy 以读取 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 更成功尝试。任何人都可以解释我如何提取我需要的字段吗?
我认为您无法从某些行(例如 'Sequence' 行)中抓取条目,因为这些行由 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
我知道有这样的问题,我一直在努力跟进。我正在尝试抓取 this 页面中的信息。理想情况下,我希望尽可能多的信息进入 clean/easy 以读取 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 更成功尝试。任何人都可以解释我如何提取我需要的字段吗?
我认为您无法从某些行(例如 'Sequence' 行)中抓取条目,因为这些行由 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