代码在下方,运行一下就知道了,此篇文章不可多说,望理解。
courseId在学习T课程页面上方的网页地址中可以获取。
如果还不清楚去下面看思路讲解。
代码如下:
import os
import requests
from bs4 import BeautifulSoup
import threading
import time
from queue import Queue
import json
'''
第一步,获取所有KnowledgeId
'''
print('获取所有KnowledgeId中...')
KnowledgeId = {}
courseId = '94924595'
# 初始url,后面需要用此url进行拼接
initUrl = 'https://mooc1.chaoxing.com/course/' + courseId + '.html'
# module=2对应课程章节,如果你的课程章节不是2,请自行修改
url = 'https://mooc1.chaoxing.com/course/' + courseId + '.html?module=2'
headers = {
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
text = requests.get(url, headers=headers).text
# 因为查找某标签用beautiful比较爽
soup = BeautifulSoup(text, "lxml")
hrefs = soup.findAll('a', class_="chapterText")
numbers = soup.findAll('i')
n = 0
for href in hrefs:
link = href.attrs['href']
title = numbers[n].get_text(separator=" ", strip=True) + href.get_text(separator=" ", strip=True)
n += 1
KnowledgeId[title] = initUrl + link
'''
第二步,根据KnowledgeId得到WorkId,这里使用多线程开启加速模式
'''
print('获取workId中,速度与您的网络情况有关,请耐心等待...')
# 无限制队列
Q = Queue()
# 任务对象列表
tasks = []
Title = []
for key, value in KnowledgeId.items():
tasks.append(value)
Title.append(key)
# 线程数
thread_num = len(tasks)
# 给列表指定一个初始长度,防止乱序
WorkId = [None] * len(tasks)
class myThread(threading.Thread):
def __init__(self, func): # 这里可以加功能函数
# 调用父类构造函数
super(myThread, self).__init__()
# 传入线程函数逻辑
self.func = func # 这里可以加功能函数
def run(self):
'''
重写run方法
'''
global Q
while not Q.empty():
# 获得任务
item = Q.get() # 取出一个队列中减少一个,没有get函数会死循环
self.func(item) # 这里可以加功能函数
'''
执行的任务
'''
# 原来写Queue,没有初始化
Q.task_done() # 发信号告诉队列此任务结束,没有done函数会一直等待
# 功能函数
def worker(item): # requests书写位置
# 设置一个指针防止乱序
p = tasks.index(item)
text = requests.get(url=item, headers=headers).text
beautiful = BeautifulSoup(text, "lxml")
try:
frame = beautiful.findAll('iframe', module="work")[0]
except:
print(Title[p] + '没有习题,跳过')
return
data = json.loads(frame.attrs['data'])
workid = data['workid']
WorkId[p] = workid
print('添加章节' + Title[p])
pass
def job(item):
p = tasks.index(item)
text = requests.get(url=item, headers=headers).text
soup = BeautifulSoup(text, "lxml")
单选题 = soup.find_all('div', style='line-height: 35px; font-size: 14px;padding-right:15px;')
选项 = soup.find_all('ul', class_='Zy_ulTop')
多选题 = soup.find_all('div', class_='Zy_TItle_p')
# 其他题型自己想办法收集
单选题.extend(多选题)
# 如果下方长度不同8成9是有没有选项新题型
# print(len(单选题))
# print(len(选项))
dic = '毛概题库'
if not os.path.exists(dic):
os.makedirs(dic)
print(f'创建{dic}文件夹')
with open(f'./{dic}/{NewTitle[p]}.txt', 'a', encoding='utf8') as f:
for i in range(0, len(单选题)):
line=单选题[i].get_text(separator=" ", strip=True)
#去除'牛逼space'
if ' ' in line:
line.replace(' ','')
try:
print(line + 选项[i].get_text(separator=" ", strip=True) + '\n')
f.write(line + 选项[i].get_text(separator=" ", strip=True) + '\n')
except:
print(line + '\n')
f.write(line + '\n')
pass
'''
其他功能性函数
'''
# 定义一个函数列表,使main能多次执行
Func = [worker, job]
# 主函数
def main(n): # 可以创建多个线程池
global Q
threads = []
# 向队列中放入任务
for task in tasks:
Q.put(task)
# 执行线程
for i in range(thread_num):
# 创建线程对象
thread = myThread(Func[n]) # 这里可以加功能函数
# 开始线程
thread.start()
# 把线程对象扔进线程池
threads.append(thread)
# 等待线程结束
for thread in threads:
# 将线程对象一个一个销毁
thread.join()
# 等待所有线程结束
Q.join()
# 本项目中执行
main(0)
'''
第三步,根据workId请求所有章节的iframe里面的题目
'''
tasks = []
NewTitle = []
m = 0
for id in WorkId:
if (id == None):
m += 1
continue
iframeUrl = 'https://mooc1.chaoxing.com/api/selectWorkQuestion?workId=' + id + '&courseId=' + courseId
tasks.append(iframeUrl)
NewTitle.append(Title[m])
m += 1
main(1)
思路讲解:python小爬虫学习思路讲解-数据挖掘文档类资源-CSDN文库
我的所有资源全部免费,如果csdn恶心到你了,请务必通知我。
这一篇我们已经获取到所有内容了,下一篇就讲讲怎么才能自动化搜索我们爬到的内容了(不拿来搜索,难道留着过年吗,一个个搜太麻烦,要自动化批量搜索才更加利于我们人前显圣)