吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6717|回复: 78
收起左侧

[Python 转载] 用python爬取限时免费开放的全部的高教社文科类教材资源

[复制链接]
龟仔龟龟 发表于 2020-2-22 19:21
本帖最后由 龟仔龟龟 于 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
于是本着练习的目的实现了上述功能,下面贴上代码,本人刚学没多久,如觉得代码简陋,请勿喷,最好能提些意见供大家学习。

代码

#!/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[i] + '.rar'
    if not os.path.exists(root):
        os.mkdir(root)
    if not os.path.exists(path):
        print(book_names[i] + '下载中')
        try:
            #构造随机浏览器访问头
            ua = UserAgent()
            ua = ua.random
            headers = {"User-Agent":ua, "Referer":"https://ct.hep.com.cn/"}
            res = requests.get(url = download_urls[i], headers = headers)
            if (res.status_code == 200):
                with open(path, 'wb') as f:
                    f.write(res.content)
                    print(book_names[i] + '下载完毕\n')
                    time.sleep(5)
            else:
                print(book_names[i] + '下载失败')
        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)):
为了方便大家使用,我将程序打包成了可执行文件
对于想自己批量下载的,我将提取链接的代码贴在了62
windows: https://fly.myroad.fun/software/win/python_spider.exe
macOS: https://fly.myroad.fun/software/mac/python_spider

效果图



Snipaste_2020-02-22_18-57-17.png
Snipaste_2020-02-22_19-51-52.png

免费评分

参与人数 12吾爱币 +9 热心值 +11 收起 理由
爱上这个小网站 + 1 我很赞同!
zeroyearn + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ligxi + 1 + 1 用心讨论,共获提升!
rice_zz + 1 + 1 用心讨论,共获提升!
hshcompass + 1 + 1 热心回复!
迷路的小和尚 + 1 谢谢@Thanks!
pyqq + 1 + 1 请问有理工类的吗???
will113 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
sukanka + 1 + 1 我很赞同!
chaff + 1 + 1 谢谢@Thanks!
一杯千年老阔乐 + 1 + 1 我很赞同!
泳诗 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

badyun 发表于 2020-2-23 10:37
本帖最后由 badyun 于 2020-2-23 10:39 编辑

嗯。。。那个悬赏帖子里面的json是我贴出来的,不过我取得方法跟你不太一样,你前面解析步骤多了,造成请求次数多了

我代码一共这么多

[JavaScript] 纯文本查看 复制代码
    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:52
本帖最后由 龟仔龟龟 于 2020-2-24 21:56 编辑

对于批量下载很简单啊,就简单改一下代码,把代码后面的下载文件部分删掉,添加一个保存下载链接的操作就可以了
[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, '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[i] + '.rar'
#    if not os.path.exists(root):
#        os.mkdir(root)
#    if not os.path.exists(path):
#        print(book_names[i] + '下载中')
#        try:
#            #构造随机浏览器访问头
#            ua = UserAgent()
#            ua = ua.random
#            headers = {"User-Agent":ua, "Referer":"https://ct.hep.com.cn/"}
#            res = requests.get(url = download_urls[i], headers = headers)
#            if (res.status_code == 200):
#                with open(path, 'wb') as f:
#                    f.write(res.content)
#                    f.close()
#                   print(book_names[i] + '下载完毕\n')
#                    time.sleep(5)
#            else:
#                print(book_names[i] + '下载失败')
#        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 00:54
本帖最后由 ligxi 于 2020-2-26 01:30 编辑

本来想请问一下楼主,关于这个真实链接"http://2d.hep.com.cn/api/v1/pan/resources/+参数",是在什么地方找到的?
刚刚又去找了一下,原来我忘记看下载文件时的消息头了看来我找的还是不够仔细啊!还是得多学习交流,这下可以安心睡觉了
搜狗截图20200226012818.png

 楼主| 龟仔龟龟 发表于 2020-2-22 19:54
cocococ 发表于 2020-2-22 19:41
下载了也不会看系列,还是节约网络资源咯,别爬瘫痪了

请求过快会被封Ip的,所以控制了下速度,添加了休眠~~~
也对,关键是用到刀口上。
卫国 发表于 2020-2-22 19:58
Python简单易学,胶水语言
ice-cream 发表于 2020-2-22 19:59
good。。。。
lihaisanhui 发表于 2020-2-22 20:01
龟仔龟龟 发表于 2020-2-22 19:54
请求过快会被封Ip的,所以控制了下速度,添加了休眠~~~
也对,关键是用到刀口上。

fake_useragent库 随机用户代{过}{滤}理(每次都不一样)这样爬小型网站就不会被封了
tomemouse 发表于 2020-2-22 20:01
Python简单易学,胶水语言
 楼主| 龟仔龟龟 发表于 2020-2-22 20:02
lihaisanhui 发表于 2020-2-22 20:01
fake_useragent库 随机用户代{过}{滤}理(每次都不一样)这样爬小型网站就不会被封了

问题是,是IP被封,应该有限制单ip的请求频率~~~我后面是挂了代{过}{滤}理才发现这个问题的
hshcompass 发表于 2020-2-22 20:17
下载了也不会看系列,还是节约网络资源咯,别爬瘫痪了
lihaisanhui 发表于 2020-2-22 20:18
龟仔龟龟 发表于 2020-2-22 20:02
问题是,是IP被封,应该有限制单ip的请求频率~~~我后面是挂了代{过}{滤}理才发现这个问题的

有没有随机换IP的办法?
top倷 发表于 2020-2-22 20:18
马了等于看了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-29 15:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表