Python:有没有一种方法可以从在线数据库的搜索结果页面上的每个href链接中的文章中抓取抽象文本



当我在在线数据库(pubmed-一个科学文章数据库)的搜索栏中输入搜索词时,我会得到一个链接列表,链接到搜索结果中的文章。我想点击每个链接,在一个新的选项卡窗口中打开每个链接,然后从摘要(摘要文章)中复制文本,这样我就可以将每个链接粘贴到一个文件中。

我最近发现,用python做这件事可能会有用得多。我知道我可以按照如下方式抓取url数据:

import requests
import bs4
root_url = 'https://www.ncbi.nlm.nih.gov/pubmed'
index_url = root_url + '/?term=%28histone%29+AND+%28chromatin%29+AND+%28hESC%29'
def get_video_page_urls():
response = requests.get(index_url)
soup = bs4.BeautifulSoup(response.text)
return [a.attrs.get('href') for a in soup.select('div.rprt a[href^=/pubmed]')]
print(get_video_page_urls())
['/pubmed/27939217', '/pubmed?linkname=pubmed_pubmed&from_uid=27939217'..... etc.

我的问题是:能否从搜索结果中的每个href链接中收集摘要文本(类似于点击链接并复制粘贴文本),然后进行分析?

最初,我尝试过:

import requests
r=requests.get('https://www.ncbi.nlm.nih.gov/pubmed/term=%28histone%29+AND+%28chromatin%29+AND+%28hESC%29')
r.content

这个结果的输出会导致搜索结果页面中的所有html文本,但我似乎找不到指定每个href链接到的文本的独特模式。所以我想知道如何隔离不同页面上的文本。。。?

Soup的设计是为了启发式地处理结构不佳的页面。对于更干净的页面和像这样简单的数据抓取,我更喜欢带有Xpath调用的LXML。要查找您想要的页面内容的XPath,请使用浏览器的Inspect功能或类似XPath Helper Wizard的浏览器插件。

这将把前20个结果和摘要转储到CSV中。要做更多的搜索词,请将其与一个词列表放在一个循环中。要获取比默认值20更多的结果,请将参数dispmax=##添加到URL中,例如。https://www.ncbi.nlm.nih.gov/pubmed?term=((组蛋白)%20AND%20染色质)%20AND%20ESC&dispmax=100

python
import unicodecsv as csv
from lxml import html
import lxml.html.clean
import requests
csv_out = open('PubMed_Abstracts.csv', 'ab')
writer = csv.writer(csv_out, dialect='excel', delimiter=',', encoding='utf-8')
writer.writerow(['Search_Term', 'Result', 'Title', 'URL', 'Abstract'])
Search_Term = '((histone)%20AND%20chromatin)%20AND%20ESC'
Search_URL = 'https://www.ncbi.nlm.nih.gov/pubmed?term=' + Search_Term #To fetch more results than the default 20, add the parameter dispmax=## to the URL, e.g. https://www.ncbi.nlm.nih.gov/pubmed?term=((histone)%20AND%20chromatin)%20AND%20ESC&dispmax=100
Search_Page = requests.get(Search_URL)
Search_Tree = html.fromstring(Search_Page.content)
# total number of results
Search_Results = Search_Tree.xpath('//h3[@class="result_count left"]/text()')
Num_Results = str([' '.join(str(result).split()) for result in Search_Results])
Num_Results_Val = Num_Results[Num_Results.find('of') + 3:-2]
# Links for results 1-20
title_cleaner = lxml.html.clean.Cleaner(allow_tags=['div', 'p', 'a'], remove_unknown_tags=False)
Title_Tree = title_cleaner.clean_html(Search_Tree)
Pub_Results = Title_Tree.xpath('//div[@class="rprt"]/div[@class="rslt"]/p[@class="title"]/a')
r = 1
for Pub_Result in Pub_Results:
Result_Num = str(r) + '/' + str(Num_Results_Val)
Pub_Title = ' '.join(Pub_Result.text_content().split())
Rel_URL = Pub_Result.get('href')
Pub_URL = Rel_URL.replace('/pubmed/', 'https://www.ncbi.nlm.nih.gov/pubmed/')
Pub_Page = requests.get(Pub_URL)
Pub_Tree = html.fromstring(Pub_Page.content)
Abstract = ''.join(Pub_Tree.xpath('//abstracttext/text()'))
writer.writerow([Search_Term, Result_Num, Pub_Title, Pub_URL, Abstract])
r += 1
csv_out.close()
exit()

您可以在这方面做更多的工作。这就是我得到的:

url="https://www.ncbi.nlm.nih.gov/pubmed/28034892"
r = requests.get(url)
print BeautifulSoup(r.content).select('div.abstr')[0].prettify()

要从这些url中获取所有摘要,您可以使用以下内容:

for a in set(get_video_page_urls()):
if len(a)<40:
url="https://www.ncbi.nlm.nih.gov" + a
r = requests.get(url)
print BeautifulSoup(r.content).select('div.abstr')[0].prettify()

您可以将其保存到某个文件中,而不用将其打印到屏幕上。

最新更新