from bs4 import BeautifulSoup # 网页解析,获取数据
import re # 正则表达式,进行文字匹配
import urllib.request,urllib.error # 制定URL,获取网页数据
import xlwt # 进行excel操作
import sqlite3 # 进行SQLlite数据库操作
# 论文编号规则
findLink = re.compile(r'<a class="docsum-title" data-article-id="(.*?)"')
# 爬取论文标题限制条件
findTitle = re.compile(r'<h1 class="heading-title">(.*?)</h1>', re.S) # 创建正则表达式对象,表示规则(字符串模式)
# 爬取论文摘要限制条件
findAbstract = re.compile(r'<p>(.*?)</p>', re.S)
def main():
baseurl = "https://pubmed.ncbi.nlm.nih.gov/?term=cardiovascular&page="
# print(askURL(baseurl))
# 1、爬取第一个网页网址
address = getAddress(baseurl)
# print(address)
# 通过论文网址爬取出论文标题以及摘要
datalist = []
for url in address:
html3 = askURL(url)
# print(html3)
soup = BeautifulSoup(html3, "html.parser")
for item in soup.find_all('h1', class_="heading-title"): # 获取标题
data = []
item = str(item)
title = re.findall(findTitle, item)[0]
title = re.sub('<br(\s+)?/>(\s+)?', " ", title)
data.append(title.strip())
for item1 in soup.find_all('div', class_="abstract-content selected" ): # 获取摘要
item1 = str(item1)
abstract = re.findall(findAbstract, item1)[0]
# if len(abstract) != 0 :
data.append(abstract.strip())
# else:
# data.append("No abstract available") # m没有概述就会为空,此时添加no abstract
datalist.append(data) # 每一个循环将data存的一篇论文的标题以及摘要放入datalist
# print(datalist)
savepath = "题目及摘要.xls" # 文件名
# 3、保存数据
saveData(datalist, savepath)
# 爬取网页html文件
def askURL(url):
head = { # 模拟浏览器服务信息,向NCBI数据库服务器发送消息
"User-Agent": "Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit/537.36(KHTML, likeGecko)Chrome / 105.0.0.0Safari / 537.36Edg / 105.0.1343.33"
}
request = urllib.request.Request(url=url, headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
# print(html)
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
return html
# 获取论文具体网址
def getAddress(baseurl):
# datalist = [] # 存放爬取到的论文信息
links = [] # 存放爬到的论文编号
address = [] # 存放论文网址+编号
html1 = "" # 存放第一个网页的HTML信息
html2 = "" # 存放第二个网页的HTML信息
for i in range(3, 4): # 调用获取页面信息的函数,从第一页爬到第11页
url1 = baseurl + str(i)
html1 = askURL(url1) # 保存获取到的一个网页源码
# 2、逐一解析第一个网页数据
soup = BeautifulSoup(html1, "html.parser") # 解析上面获取到的HTML文件,形成树形结构数据,便于后面对所需字段筛选
for wrap in soup.find_all('div', class_="docsum-wrap"): # 查找符合要求的字符串,形成列表
# print(wrap) # 测试:查看论文wrap全部信息
wrap = str(wrap)
# 获取到论文的编号
link = re.findall(findLink, wrap)[0] # re库用来通过正则表达式查找指定的字符串,添加论文编号
links.append(link) # 每次爬到一个论文编号就把编号放到links列表中
# print(links)
# 获取到所有编号后,通过编号爬取编号所对应的论文信息
for num in links:
url2 = 'https://pubmed.ncbi.nlm.nih.gov/' + num # 论文编号
address.append(url2)
return address
def saveData(datalist, savepath):
book = xlwt.Workbook(encoding="utf-8", style_compression=0) # 创建wookbook对象
sheet = book.add_sheet('题目及摘要', cell_overwrite_ok=True) # 创建工作表
col = ('论文题目', '论文摘要')
for i in range(0, 2): # 将列名放入表格
sheet.write(0, i, col[i])
for i in range(len(datalist)):
# print("写入第%d条数据" % i)
data = datalist[i]
if len(data) == 2: # 有摘要的论文data=2,没有摘要的论文data=1
for j in range(0, 2):
sheet.write(i + 1, j, data[j])
else:
for j in range(0, 1): # 没有摘要,只写第一项
sheet.write(i + 1, j, data[j])
book.save(savepath)
if __name__ == "__main__": # 当程序执行时
# 调用函数,
main()
print("爬取完毕")
爬取论文网站NCBI论文标题以及摘要
最新推荐文章于 2024-05-11 16:36:07 发布