Получить данные PubMed из ID с помощью bs4

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

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'

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


person Toby    schedule 06.11.2016    source источник


Ответы (1)


Я не знаю, как выглядит ваш файл 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:

7 июля 2016 г. Уточнение и проверка карт криоэлектронной микроскопии суб-5 на основе молекулярной динамики. Два метода определения структуры, основанные на молекулярно-динамическом гибком подборе [...]

Обязательно удалите не-ascii-символы через encode, иначе многие аннотации и заголовки будут давать вам ошибки.

person Maximilian Peters    schedule 08.11.2016
comment
@Toby: Вы можете использовать его, как в приведенном выше примере, abstract.encode('ascii', 'ignore'), попытается закодировать его как ascii и удалить все символы, которые не подходят. - person Maximilian Peters; 21.11.2016