如何快速爬取国内985大学学术学报pdf文件

背景

最近,在爬取关于国内985大学的学报时,我注意到大部分大学学报站点格式都采用相似的形式,并且PDF链接都使用自增的ID。然而,我也发现了一个问题,即大多数PDF链接的ID并不是连续的。现在我将向你分享一些方法,以快速获取所有的大学学报PDF链接。

首先通过最新期刊和最旧的期刊查找pdf链接的id范围:

最新期刊为 2023-03-20

最旧期刊为 2013-01-30

点击进去后下载pdf后,在开发者工具可以发现链接上的id最大在1000左右,最小的id在个位数。

当我们请求不存在的id会发现response.headers.get('Content-Type')为html类型,而正确的id响应类型则为application/x-download。

python 复制代码
response = session.get(
    f'http://journal.pku.edu.cn/CN/article/downloadArticleFile.do?attachType=PDF&id=105',  #id为105,不正确的id
    cookies=cookies,
    headers=headers,
	verify=False)

print(response.headers.get('Content-Type') )

输出:

text/html;charset=UTF-8

python 复制代码
response = session.get(
    f'http://journal.pku.edu.cn/CN/article/downloadArticleFile.do?attachType=PDF&id=1',
    cookies=cookies,
    headers=headers,
stream=True, verify=False)
print(response.headers.get('Content-Type') )

输出:

application/x-download

如果使用head请求虽然可以快速获取所有响应类型,而无需请求响应体。但这里如果你发现使用requests.head方法返回的headers和使用requests.get方法返回的headers不一致,那可能是由于服务器对不同类型请求返回的header信息不同导致的。

我们可以通过覆盖爬取获取每个刊期不同链接上的id,但需要写一堆xpath或正则,所有这里不使用这个方法。

快速爬取pdf链接

我们可以使用request的stream=True方法快速请求url获取pdf链接

在requests库中,stream参数用于控制响应是否以流的方式进行处理。默认情况下,stream参数的值为False,表示禁用流式处理,整个响应内容会一次性加载到内存中。

当stream参数设置为True时,表示启用流式处理,响应内容会以流的形式逐步传输,而不是一次性加载到内存中。这在处理大型响应体或需要逐步处理数据的情况下很有用。

当stream为True时,可以使用close方法关闭请求,就不需要进行请求响应体,可以节省更多资源和时间去请求其他url

完整代码:

python 复制代码
import requests,time
from requests.adapters import HTTPAdapter, Retry
import threading

url_id = []
def get_response(id):
    cookies = {
        'JSESSIONID': '1EEC758D35D23CE4721E1419871575C6',}
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'Accept-Language': 'zh-CN,zh;q=0.9,ja;q=0.8',
        'Connection': 'keep-alive',
        'Range': 'bytes=0-0.1' ,
        # 'Cookie': 'JSESSIONID=1EEC758D35D23CE4721E1419871575C6',
        'Referer': 'http://journal.pku.edu.cn/CN/abstract/abstract1015.shtml',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
    }
    session = requests.Session()
    retries = Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504])
    session.mount('http://', HTTPAdapter(max_retries=retries))

    response = session.get(
        f'http://journal.pku.edu.cn/CN/article/downloadArticleFile.do?attachType=PDF&id={id}',
        cookies=cookies,
        headers=headers,
    stream=True, verify=False)
    if response.headers.get('Content-Type') == 'application/x-download':
        response.close
        url_id.append(id)
    else:
        print('无效id-------',id,response.headers.get('Content-Type'))
    return response.headers.get('Content-Type') 

threads = []
for i in range(2000):
    thread = threading.Thread(target=get_response, args=(i,))
    thread.start()
    threads.append(thread)

for td in threads:
    td.join()

输出:

通过输出可以发现id不是连续的,并且代码运行耗时1分半钟,速度也比直接get请求不使用stream=True快出几十倍。

通过请求上述代码中的url_id 列表里的有效id,我们就可以直接下载pdf了。这个站点pdf数据不多,但国内大学站点大部分都可以采用这种形式爬取。

相关推荐
不写八个3 小时前
Python办公自动化教程(001):PDF内容提取
开发语言·python·pdf
碎像4 小时前
使用Python免费将pdf转为docx
python·pdf·word
南七澄江4 小时前
python爬虫:将知乎专栏文章转为pdf
爬虫·python·pdf
大熊程序猿7 小时前
libreoffice word转pdf
pdf·word
大熊程序猿11 小时前
go libreoffice word 转pdf
pdf
aluluka20 小时前
PDF标准详解(五)——图形状态
pdf
eybk2 天前
改进拖放PDF转换为图片在转换为TXT文件的程序
pdf
Arisono2 天前
财富之眼用经济思维看清世界PDF高清下载
pdf
Arisono2 天前
android google play应用发布上架流程PDF下载
pdf
皮肤科大白2 天前
无法将ggplot图保存为PDF文件怎么办
pdf