用python爬取限时免费开放的全部的高教社文科类教材资源
本帖最后由 龟仔龟龟 于 2020-2-27 18:54 编辑## 前言
最近学习了**Python** , 看到悬赏板块有坛友求批量下载
https://www.52pojie.cn/forum.php?mod=viewthread&tid=1112761&extra=page%3D1%26filter%3Dspecialtype%26specialtype%3Dreward
资源地址:
https://ct.hep.com.cn/public/page/wk.html
于是本着练习的目的实现了上述功能,下面贴上代码,本人刚学没多久,如觉得代码简陋,请勿喷,最好能提些意见供大家学习。
## 代码
```python
#!/usr/bin/python3
#演示平台Windows10
#Mac、Linux系统请自行更改目录
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
import os
import time
#资料保存的根目录
root = 'F:\\book\\'
#构造浏览器访问头
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 \
(KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36",
"Referer":"https://ct.hep.com.cn/"}
#创建一个列表
#存储资料一级下载地址(因为会有两个302跳转)
resource_urls = []
for i in range(25,1151,25):
# 这些数字是通过分析得来的
# URL的构造同理(开发者控制台分析)
resource_url = 'https://ct.hep.com.cn/public/page/wk-listData.html?' + \
'pageConfig=%257B%2522start%2522%253A' + str(i) + \
'%252C%2522limit%2522%253A25%252C%2522condition%2522%253A%255B%255D%257D'
resource_urls.append(resource_url)
#创建两个列表
#分别存储二级下载地址和书名
download_urls = []
book_names = []
for resource_url in resource_urls:
#提取页面信息
r = requests.get(url = resource_url, headers = headers)
r.encoding = r.apparent_encoding
soup = BeautifulSoup(r.text, 'lxml')
name = soup
#进一步提取信息
soup = soup.find_all('div', 'col-lg-2 col-md-2 col-sm-6 col-xs-6 btnDown')
names = name.find_all('div', 'col-lg-6 col-md-6 col-sm-12 col-xs-12')
for name in names:
book_names.append(name.get_text())
#从一级下载界面提取URL
for elem in soup:
elem = elem.find('a')
elem = elem.get('href')
#转换为我们需要的最终下载URL
sep = elem.split('/')
complete_url = 'http://2d.hep.com.cn/api/v1/pan/resources/' + sep[-2] + '/download'
download_urls.append(complete_url)
#分别下载资料
for i in range(len(book_names)):
#path为资料完整路径
path = root + book_names + '.rar'
if not os.path.exists(root):
os.mkdir(root)
if not os.path.exists(path):
print(book_names + '下载中')
try:
#构造随机浏览器访问头
ua = UserAgent()
ua = ua.random
headers = {"User-Agent":ua, "Referer":"https://ct.hep.com.cn/"}
res = requests.get(url = download_urls, headers = headers)
if (res.status_code == 200):
with open(path, 'wb') as f:
f.write(res.content)
print(book_names + '下载完毕\n')
time.sleep(5)
else:
print(book_names + '下载失败')
except Exception:
pass
```
**刚才添加了休眠时间,防止请求过快,会封IP,一次没下完,下次运行可以接着**
**第一部分(1-300)打包下载**: https://csueducn-my.sharepoint.com/personal/bobmaster_csu_edu_cn/_layouts/52/download.aspx?share=ERFpStkcTC1Hu0FybkRuU7QBnN7ZgvwzVqtsp21ZO-m8bg
**第二部分(301-600)打包下载**:https://csueducn-my.sharepoint.com/personal/bobmaster_csu_edu_cn/_layouts/52/download.aspx?share=EeH28z_N6rhArnwN_YmOOqIB8FQidtIWCRyY1gP6yno1Ng
**后面部分自行改代码,服务器空间不够了,你们就把for i in range(len(book_names)):改为for i in range(600.len(book_names)):**
**为了方便大家使用,我将程序打包成了可执行文件**
**对于想自己批量下载的,我将提取链接的代码贴在了(https://www.52pojie.cn/forum.php?mod=redirect&goto=findpost&ptid=1113195&pid=30185680)楼**
windows: https://fly.myroad.fun/software/win/python_spider.exe
macOS: https://fly.myroad.fun/software/mac/python_spider
## 效果图
本帖最后由 badyun 于 2020-2-23 10:39 编辑
嗯。。。那个悬赏帖子里面的json是我贴出来的,不过我取得方法跟你不太一样,你前面解析步骤多了,造成请求次数多了
我代码一共这么多
let s = await superagent.post('https://ct.hep.com.cn/public/page/wk-listData.html')
.type('form')
.send({
pageConfig: encodeURI(JSON.stringify({ "start": 0, "limit": 2000, "condition": [] }))
})
let $ = cheerio.load(s.text)
let e = []
$('.row').each((i, ele) => {
e.push({
title: $(ele).find('.col-xs-12').text(),
name: $(ele).find('.name').text(),
path: 'http://2d.hep.com.cn/api/v1/pan/resources/' + $(ele).find('a').attr('href').replace('/download', '').replace('http://www.hep.com.cn/pan/r/', '') + '/download'
})
})
fs.writeFileSync('./book.json', JSON.stringify(e, null, '\t'))
他post请求的pageConfig的参数通过url解码可以获取到一个json对象,
里面start关键字是起始项,limit是一页多少个。
而他总个数是1162条,
所以直接start为0,limit为任何一个大于等于1162的数,就可以获取到所有书籍链接
本帖最后由 龟仔龟龟 于 2020-2-24 21:56 编辑
will113 发表于 2020-2-24 20:46
大佬来一个。
对于批量下载很简单啊,就简单改一下代码,把代码后面的下载文件部分删掉,添加一个保存下载链接的操作就可以了
#!/usr/bin/python3
#演示平台Windows10
#Mac、Linux系统请自行更改目录
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
import os
import time
#资料保存的根目录
root = 'F:\\book\\'
#构造浏览器访问头
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 \
(KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36",
"Referer":"https://ct.hep.com.cn/"}
#创建一个列表
#存储资料一级下载地址(因为会有两个302跳转)
resource_urls = []
for i in range(25,1151,25):
# 这些数字是通过分析得来的
# URL的构造同理(开发者控制台分析)
resource_url = 'https://ct.hep.com.cn/public/page/wk-listData.html?' + \
'pageConfig=%257B%2522start%2522%253A' + str(i) + \
'%252C%2522limit%2522%253A25%252C%2522condition%2522%253A%255B%255D%257D'
resource_urls.append(resource_url)
#创建两个列表
#分别存储二级下载地址和书名
download_urls = []
book_names = []
for resource_url in resource_urls:
#提取页面信息
r = requests.get(url = resource_url, headers = headers)
r.encoding = r.apparent_encoding
soup = BeautifulSoup(r.text, 'html.parser')
name = soup
#进一步提取信息
soup = soup.find_all('div', 'col-lg-2 col-md-2 col-sm-6 col-xs-6 btnDown')
names = name.find_all('div', 'col-lg-6 col-md-6 col-sm-12 col-xs-12')
for name in names:
book_names.append(name.get_text())
#从一级下载界面提取URL
for elem in soup:
elem = elem.find('a')
elem = elem.get('href')
#转换为我们需要的最终下载URL
sep = elem.split('/')
complete_url = 'http://2d.hep.com.cn/api/v1/pan/resources/' + sep[-2] + '/download'
download_urls.append(complete_url)
#保存下载链接,方便用IDM批量下载
with open('url.txt', 'w', encoding='utf-8') as f:
for url in download_urls:
f.write(url + '\n')
f.close()
#分别下载资料
#for i in range(len(book_names)):
# #path为资料完整路径
# path = root + book_names + '.rar'
# if not os.path.exists(root):
# os.mkdir(root)
# if not os.path.exists(path):
# print(book_names + '下载中')
# try:
# #构造随机浏览器访问头
# ua = UserAgent()
# ua = ua.random
# headers = {"User-Agent":ua, "Referer":"https://ct.hep.com.cn/"}
# res = requests.get(url = download_urls, headers = headers)
# if (res.status_code == 200):
# with open(path, 'wb') as f:
# f.write(res.content)
# f.close()
# print(book_names + '下载完毕\n')
# time.sleep(5)
# else:
# print(book_names + '下载失败')
# except Exception:
# pass
为了方便大家使用,我将程序打包成了可执行文件
windows: https://fly.myroad.fun/software/win/python_spider.exe
macOS: https://fly.myroad.fun/software/mac/python_spider 马了等于看了 本帖最后由 ligxi 于 2020-2-26 01:30 编辑
本来想请问一下楼主,关于这个真实链接"http://2d.hep.com.cn/api/v1/pan/resources/+参数",是在什么地方找到的?
刚刚又去找了一下,原来我忘记看下载文件时的消息头了{:301_1007:}看来我找的还是不够仔细啊!还是得多学习交流,这下可以安心睡觉了{:1_900:}
cocococ 发表于 2020-2-22 19:41
下载了也不会看系列,还是节约网络资源咯,别爬瘫痪了
请求过快会被封Ip的,所以控制了下速度,添加了休眠~~~
也对,关键是用到刀口上。 Python简单易学,胶水语言 good。。。。 龟仔龟龟 发表于 2020-2-22 19:54
请求过快会被封Ip的,所以控制了下速度,添加了休眠~~~
也对,关键是用到刀口上。
fake_useragent库 随机用户代{过}{滤}理(每次都不一样)这样爬小型网站就不会被封了 Python简单易学,胶水语言{:1_913:} lihaisanhui 发表于 2020-2-22 20:01
fake_useragent库 随机用户代{过}{滤}理(每次都不一样)这样爬小型网站就不会被封了
问题是,是IP被封,应该有限制单ip的请求频率~~~我后面是挂了代{过}{滤}理才发现这个问题的 下载了也不会看系列,还是节约网络资源咯,别爬瘫痪了 龟仔龟龟 发表于 2020-2-22 20:02
问题是,是IP被封,应该有限制单ip的请求频率~~~我后面是挂了代{过}{滤}理才发现这个问题的
有没有随机换IP的办法?