Python爬虫自动爬取拉钩教育课程文章并保存成PDF

2022-08-07,,,

背景:

前段时间写了一篇Python爬虫爬取拉钩教育视频的博客,有朋友留言说改写下爬取文章,今天有空改了改…
爬取视频版:https://blog.csdn.net/Mr_Renxiansheng/article/details/106313236

运用到的技术点总结

1、线程
2、队列
3、requests库
4、json
5、pdfkit
注意:由于需要保存成PDF,我这里用了pdfkit,使用前得先安装[http://wkhtmltopdf http://wkhtmltopdf.org/downloads.html](https://wkhtmltopdf%20%20http://wkhtmltopdf.org/downloads.html) windows选择 选择 7z Archive 下载解压即可

正文

基本流程同爬取视频一样。
pdfkit 有一个方法是from_string 通过这个方法可以将string转换成pdf,所以我们这里只需要找到课程文章的HTML并转成str,最后丢到pdfkit转换就可以了,具体实现如下:
打开文章页面,通过查看源码可以发现,课程文章并不在源码中,所以我们这里需要通过抓包的形式来获取。 直接F12,刷新后抓包

通过分析可以发现这个响应里面有文章的html,查看请求url
https://gate.lagou.com/v1/neirong/kaiwu/getCourseLessonDetail?lessonId=xxx
最后的数字是课程的id,为了一次性爬取所有课程文章,那么就需要知道所有课程文章的id,继续分析请求…

找到课程文章id了,通过https://gate.lagou.com/v1/neirong/kaiwu/getCourseLessonDetail?lessonId=(id)就可以拼接成正确的url了,最后通过这个url获取课程文章的html

到了这里基本上思路都已经通了,简单总结下:
1、找到所有课程文章的id,用来拼接正确的url
2、通过抓包分析找到课程文章html的请求url,解析得到html
3、将html转换成pdf

好了上具体代码:


import threading
from queue import Queue
import requests
import json
import time
import pdfkit




class LaGou_spider():
    def __init__(self):
        self.url = 'https://gate.lagou.com/v1/neirong/kaiwu/getCourseLessons?courseId=17'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
            'Cookie': '请使用自己的Cookie',
            'Referer': 'https://kaiwu.lagou.com/course/courseInfo.htm?courseId=17',
            'Origin': 'https://kaiwu.lagou.com',
            'Sec-fetch-dest': 'empty',
            'Sec-fetch-mode': 'cors',
            'Sec-fetch-site': 'same-site',
            'x-l-req-header': '{deviceType:1}'}
        self.textUrl='https://gate.lagou.com/v1/neirong/kaiwu/getCourseLessonDetail?lessonId='  #发现课程文章html的请求url前面都是一样的最后的id不同而已
        self.queue = Queue()  # 初始化一个队列
        self.error_queue = Queue()

    def parse_one(self):
        """

        :return:获取文章html的url
        """
        # id_list=[]
        html = requests.get(url=self.url, headers=self.headers).text
        dit_message = json.loads(html)
        message_list = dit_message['content']['courseSectionList']
        # print(message_list)
        for message in message_list:
            for i in message['courseLessons']:
                true_url=self.textUrl+str(i['id'])
                self.queue.put(true_url)#文章的请求url


        return self.queue

    def get_html(self,true_url):
        """

        :return:返回一个Str 类型的html
        """
        html=requests.get(url=true_url,timeout=10,headers=self.headers).text
        dit_message = json.loads(html)
        str_html=str(dit_message['content']['textContent'])
        article_name=dit_message['content']['theme']
        self.htmltopdf(str_html,article_name)

    def htmltopdf(self,str_html,article_name):
        path_wk = r'D:\wkhtmltox-0.12.6-1.mxe-cross-win64\wkhtmltox\bin\wkhtmltopdf.exe'
        config = pdfkit.configuration(wkhtmltopdf=path_wk)
        options = {
            'page-size': 'Letter',
            'encoding': 'UTF-8',
            'custom-header': [('Accept-Encoding', 'gzip')]
        }
        pdfkit.from_string(str_html,"{}.pdf".format(article_name),configuration=config,options=options)



    def thread_method(self, method, value):  # 创建线程方法
        thread = threading.Thread(target=method, args=value)
        return thread

    def main(self):

        thread_list = []
        true_url= self.parse_one()
        while not  true_url.empty():
            for i in range(10):  # 创建线程并启动
                if not true_url.empty():
                    m3u8 = true_url.get()
                    print(m3u8)
                    thread = self.thread_method(self.get_html, (m3u8,))
                    thread.start()
                    print(thread.getName() + '启动成功,{}'.format(m3u8))
                    thread_list.append(thread)
                else:
                    break
            while len(thread_list)!=0:
                for k in thread_list:
                    k.join()  # 回收线程
                    print('{}线程回收完毕'.format(k))
                    thread_list.remove(k)



run = LaGou_spider()
run.main()


注意:

请控制下爬取的速度,太快可能会导致账号被封…大饼在调试程序的过程中曾被封过,过了一段时间后才恢复…

本文地址:https://blog.csdn.net/Mr_Renxiansheng/article/details/107230524

《Python爬虫自动爬取拉钩教育课程文章并保存成PDF.doc》

下载本文的Word格式文档,以方便收藏与打印。