2016-11-06 13 views
0

Я работаю над проектом, чтобы загрузить заголовок, реферат, год публикации и условия MeSH из файла CSV размером ~ 12 000 идентификаторов PubMed. Я написал код ниже:Получите данные PubMed из ID с помощью bs4

import urllib2 
from bs4 import BeautifulSoup 
import csv 

CSVfile = open('srData.csv') 
fileReader = csv.reader(CSVfile) 
Data = list(fileReader) 
i = 0 

with open('blank.csv','wb') as f1: 
writer=csv.writer(f1, delimiter='\t',lineterminator='\n',) 
for id in Data: 
    soup = BeautifulSoup(urllib2.urlopen("http://www.ncbi.nlm.nih.gov/pubmed/" & id).read()) 
    jouryear = soup.find_all(attrs={"class": "cit"}) 
    year = jouryear[0].get_text() 
    yearlength = len(year) 
    titleend = year.find(".") 
    year1 = titleend+2 
    year2 = year1+1 
    year3 = year2+1 
    year4 = year3+1 
    year5 = year4+1 
    published_date = (year[year1:year5]) 

    title = soup.find_all(attrs={"class": "rprt abstract"}) 
    title = (title[0].h1.string) 

    abstract = (soup.find_all(attrs={"class": "abstr"})) 
    abstract = (abstract[0].p.string) 
    writer.writerow([published_date, title, abstract]) 
    i = i+1 
    print i 

Когда я запускаю его, я получаю следующее сообщение об ошибке:

TypeError: unsupported operand type(s) for &: 'str' and 'list' 

Как я могу это исправить? Я также испытываю проблему, когда год и название и пишутся в одной и той же ячейке, но мне нужны они в разных столбцах. Что я могу сделать, чтобы исправить это?

ответ

0

Я не знаю, как выглядит ваш файл srData.csv, но если это всего лишь список идентификаторов, например.

27383269 
27281200 

вы бы использовать id[0] вместо id, в противном случае ваш являются конкатенации в list и string.

Для того, чтобы получить опубликованные данные, название и аннотация, вы можете получить данные с помощью следующих строк кода:

published_date = soup.find_all(attrs={"class": "cit"})[0].get_text().split('.')[1].split(';')[0].strip() 
     title = soup.find_all(attrs={"class": "rprt abstract"})[0].h1.string 
     abstract = soup.find_all(attrs={"class": "abstr"})[0].p.string 
     writer.writerow([published_date, title.encode('ascii', 'ignore'), abstract.encode('ascii', 'ignore')]) 

Дата немного сложнее и требует, чтобы извлечь из всей цитаты, но все остальные могут читать напрямую.

Выход для Pubmed ID 27383269:

2016 Jul 7 Molecular dynamics-based refinement and validation for sub-5 cryo-electron microscopy maps. Two structure determination methods, based on the molecular dynamics flexible fitting (MDFF) [...]

Убедитесь, чтобы удалить не-ASCII символов через encode, иначе много рефератов и заголовков будет выдавать ошибку.

+0

Как использовать кодировку? – Toby

+0

@Toby: вы можете использовать его как в приведенном выше примере, abstract.encode ('ascii', 'ignore'), попытается закодировать, чтобы закодировать его как ascii и удалить все символы, которые не подходят. –