用python爬取当日arXiv上的文章的标题和链接
之前学习了python,一直只用来进行数值计算。但是想用python干别的点事情,发现爬虫很简单,于是学习了州的先生写的爬虫的文章。打算干点啥用来练一练手,这里来分享一个用爬虫技术做的一个小程序。
做科研最重要的事情之一就是看文章,所以获取文章很重要。arXiv是一个收集物理学,数学,计算机科学,生物学预印本的一个网站。这个网站有几个特点,首先是每天更新的(周一到周五),第二是方向分门别类很细致,和自己相关的往往就一个或者几个,还有这个网站获取文章是免费的。当然这个优秀的网站特点有很多,值得我们细细探索。
于是我写了一个小程序来获取arXiv当天一个方向(quantum Physics)的所有文章的链接和标题,方便浏览,当然遇到有用的文章可以直接点击链接查看。当然我没有利用爬虫从这个网站上下载任何文章,只是获取title和link, 因为这个网站是禁止机器人爬取的.
具体的程序就写在下边:
import os
import requests
import time
from bs4 import BeautifulSoup
# DW = input('The chosen day is ')
# DW = 1
url = 'https://arxiv.org/list/quant-ph/recent'
header = {
'Host': 'arxiv.org',
'Accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'
}
r1 = requests.get(url, headers=header)
soup = BeautifulSoup(r1.content, 'lxml')
##当日是周几 date, 有多少文章 total
text_dl = soup.select('div#dlpage > h3')
text_ds = text_dl[0].get_text()
text_d = text_ds.split()
date = text_d[0]
total = int(text_d[8])
print('Today is ', date, '. And ', total, 'papers are new')
##
## 当日文章分为几页page+1,以及最后一页有多少条rest
page, rest = divmod(total, 25)
list_page = range(1, page + 1)
##定义获取数据的函数
def get_all_this_page(url):
header = {
'Host': 'arxiv.org',
'Accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'
}
rr = requests.get(url, headers=header)
soup2 = BeautifulSoup(rr.content, 'lxml')
linkall0 = soup2.select('div#dlpage > dl > dt > span > a:nth-child(1)')
titleall0 = soup2.select(
'div#dlpage > dl > dd > div > div.list-title.mathjax')
number0 = soup2.select('div#dlpage > dl > dt > a')
return linkall0, titleall0, number0
##第一页比较特殊,单独拿出来
linkall = []
titleall = []
number = []
fir = get_all_this_page(url)
linkfir = fir[0]
titlefir = fir[1]
numberfir = fir[2]
for qq in range(0, 25):
linkall.append(linkfir[qq].get('href'))
titleall.append(titlefir[qq].get_text())
number.append(numberfir[qq].get_text())
##获取每一页的连接
##从第二页开始循环到最后一页,最后一页特殊,单独拿出来
for ii in list_page:
urlmid = 'https://arxiv.org/list/quant-ph/pastweek?skip=' + str(
ii * 25) + '&show=25'
mid = get_all_this_page(urlmid)
linkmid = mid[0]
titlemid = mid[1]
numbermid = mid[2]
if ii < page:
for jj in range(0, 25):
linkall.append(linkmid[jj].get('href'))
titleall.append(titlemid[jj].get_text())
number.append(numbermid[ii].get_text())
else:
for jj in range(0, rest):
linkall.append(linkmid[jj].get('href'))
titleall.append(titlemid[jj].get_text())
number.append(numbermid[ii].get_text())
##将相对链接换为绝对链接
for pp in range(0, total):
link = 'https://arxiv.org/' + linkall[pp]
linkall[pp] = link
##写入文本
with open('test_arxiv.txt', 'w') as data:
for mm in range(0, total):
data.write(number[mm] + '\n')
data.write(linkall[mm])
data.write(titleall[mm])
基本的想法就是,首先找到这个网站中的recent页面(程序中的url),之后查看当日更新的文章有多少(total),然后分为几页分别获取题目和链接,最后将结果输出到一个txt文件中。这里面唯一一个需要注意的地方就是,因为该网站每一页默认是展示25个,但是如果当日的更新大于25条的话就需要换下一页继续爬取,我们看到下一个25页链接的特点是skip25&show=25,对于再下一页则是skip50&show=25,所以我们就可以获取到任意页码的链接。当然该网站还提供了查看每页多余25个甚至是本周全部条目的方法,所以也可以采取加载全部之后爬取一部分的方法。
以下是txt文件的部分结果:
[1]
https://arxiv.org//abs/2002.12295
Title: Semi-Device-Independent Random Number Generation with Flexible Assumptions
[2]
https://arxiv.org//abs/2002.12252
Title: Fundamental limits of quantum illumination
[3]
https://arxiv.org//abs/2002.12216
Title: Sum-of-squares decompositions for a family of non-contextuality inequalities and self-testing of quantum devices
当然这是一个简单的小程序,有需要的人可以参考以下。
其实这个程序本来的目的是获取当日或者本周任意一天的文章的title和link,这个小程序只是第一步,下一步计划就是可以输入任意一天的程序。然后为了阅读方便还计划利用pylatex将结果放到pdf文件中,这是第三步。