爬虫系列教程四:动态网页api分析实例之爬取dropbox上的pdf

动态网页api分析实例:爬取dropbox上的pdf

今天老师让我下载一个网课里面的pdf材料,pdf的数目比较多,一部分pdf是放在dropbox上面的,看了一下是一个动态网页。想起来我的爬虫教程好久没填坑了,今天我就打算拿爬虫来完成这个任务,顺便写个教程,我今天选择的方式是分析api,下次再遇到动态网页写博客的时候,我就用js引擎(flag已经立下了)。废话不多说,下面开始。

任务

  1. 爬取的页面:https://aisecure.github.io/TEACHING/cs598.html
    网页
  2. 具体爬取要求,根据时间创建文件夹,然后把当天的所有pdf文件放在文件夹中;

分析

  1. 拿到任务后我首先分析了一下要爬取的文件:一类是论文,一类是幻灯片;论文比较好爬取,但是幻灯片是放在dropbox上面的,有一定难度;
  2. 这个主页面是一个静态的页面,没啥难度,拿到网页信息后对网页结构解析后搜索一下,就能拿到我们需要爬取内容。
    • 其中论文部分的url比较好分析,直接从对应元素的href属性中拿到pdf的url:
      • 大部分的论文是挂在了arxiv上,但是有的链接是直接指向pdf文件的,有的链接就没有,需要+’.pdf’;
        修改
      • 还有论文是在openreview上面的,把链接中的forum改成pdf就可以下载了;
        更改
      • 其它的论文都通过链接可以直接下载;
        直接下载
    • dropbox上面的pdf文件的下载链接是放在动态网页上的的,所以需要费点周折。本次采用的方式是分析api。首先抓一波包,发现点击了立即下载的按钮后,有两个包比较重要
      • 第一个包是下载pdf文件的包
        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0JD9lSwC-1616418037476)(https://raw.githubusercontent.com/Richardhongyu/pic/main/20210322201751.png)]
        • 携带参数
          携带参数
        • 经过观察_download_id和request url两部分是根据下载的pdf变化的
      • 然后看到第二个包
        第二个包
        • 它的responce里面有下载链接的一部分,
          responce
        • 经过观察第一个包将第二个包的response和某些参数组合为它的request url,从而得到了pdf文件。
        • 现在需要得到这个包的携带参数
          携带参数
          • 经过观察,第一个参数is_xhr和第二个参数t都是固定的,第三个参数和这个pdf的url,所以这个api就分析完了
      • 再返回来分析第一个包
        • 现在第一个包就短_download_id未知了,推测是在js代码里面生成的,所以观察使用过的js函数
          js函数
        • 经过阅读和搜索找到了这个地方
          关键代码
          • 原来就是个随机数。。。分析到这个地方,我尬住了,原来还以为有个加密函数的,没想到直接是随机数,那你加这玩意干啥。上网一查,原来是为了每次的url不一样避免缓存
        • 所以第一个包也就解决了,直接用一个固定的_download_id就可以

写代码和debug

  1. 注意事项

    • 下面就是正常的写代码和debug环节了,这里列出了一些坑:
    • 因为dropbox是国外的,需要挂代理
    • 因为爬取的是pdf,需要用open方式保存到本地文件
    • 在访问第一个包的时候,需要添加cookies,否则会有403错误
    • 爬取过程中发现有的资源丢失了,所以做了异常处理
  2. 具体代码

    import requests
    from bs4 import BeautifulSoup
    import os
    import re
    
    # use proxies to speed up
    proxies = {
    "http": "socks5://127.0.0.1:10808",
    "https": "socks5://127.0.0.1:10808",
    }
    data = requests.get("https://aisecure.github.io/TEACHING/cs598.html")
    soup = BeautifulSoup(data.content, 'html.parser')
    entries = soup.find_all("tr")
    entries = list(entries)
    
    for k, i in enumerate(entries[1:]):
        i = str(i)
        entry_data = BeautifulSoup(i, 'html.parser')
        date_and_sides = entry_data.find_all(class_="tg-0pky")
        readings = entry_data.find_all(class_="tg-reading")
        if date_and_sides!= []:
            date_list = str.split(date_and_sides[0].string, '/') 
            print(date_list)
            month = date_list[0]
            day = date_list[1]
            if len(month)==1:
                month = '0'+month
            if len(day)==1:
                day = '0'+day
            month_day = month+day
            print(month_day)
        
        if len(date_and_sides) == 2:
            if not os.path.exists(month_day):
                os.mkdir(month_day)
            if readings!=[]:#readings
                readings = str(readings[0])
                readings = BeautifulSoup(readings, 'html.parser')
                for link in readings.find_all('a'):
                    pdf_link = link.get('href')
                    if 'http' not in pdf_link:
                        break
                    elif 'openreview' in pdf_link:
                        pdf_link = pdf_link.replace('forum', 'pdf')
                    elif 'arxiv' in pdf_link and 'pdf' not in pdf_link:
                        pdf_link = pdf_link + '.pdf'
                    print(pdf_link)
                    pdf_name = pdf_link.split('/')[-1]
                    if '.pdf' not in pdf_name:
                        pdf_name = pdf_name.split('=')[-1]+'.pdf'
                    print(pdf_name)
    
                    pdf_data = requests.get(pdf_link, proxies=proxies)
                    f = open(month_day+'/'+pdf_name,'wb')                      
                    f.write(pdf_data.content)                       
                    f.close()
            slides = date_and_sides[1]#slides
            slides = str(slides)
            slides = BeautifulSoup(slides, 'html.parser')
            for link in slides.find_all('a'):
                pdf_link = link.get('href')
                print(pdf_link)
                if 'dropbox' in pdf_link and k!=9 and k!=10:#k==9, slide file is in google driver, we don't have access to it;10 file not exits
                    url = 'https://www.dropbox.com/sharing/fetch_user_content_link'
                    cookies = {'__Host-ss':'bcD4Chza3M', 'locale':'zh_CN', 'gvc':'MTQxMzI3NDU0NjU2NzAyODExNDM4MzQ3NTk2NDExMjgyNjc2MzI2', 't':'-VB7vYgNnBuMG3LhS_GfEzTL', '__Host-js_csrf':'-VB7vYgNnBuMG3LhS_GfEzTL', 'seen-sl-signup-modal':'VHJ1ZQ%3D%3D', 'seen-sl-download-modal':'VHJ1ZQ%3D%3D'}
                    data={
                        'is_xhr': 'true',
                        't': '-VB7vYgNnBuMG3LhS_GfEzTL',
                        'url': pdf_link
                    }
                    slide_data = requests.post(url, data=data, proxies = proxies, cookies = cookies)
                    middle_url = str(slide_data.content)
                    print(middle_url)
                    middle_url = middle_url.split('?')[0]
                    middle_url = middle_url[2:]
                    data_2={
                        '_download_id':'013885563736029338651059959499724834269999834692877836324471532568',
                        '_notify_domain':'www.dropbox.com',
                        'dl':'1'
                    }
                    pdf_data = requests.get(middle_url, data=data_2, proxies = proxies)
                    pdf_name = pdf_link.split('/')[-1]
                    pdf_name = pdf_name.split('?')[0]
                    print(pdf_name)
                    f = open(month_day+'/'+pdf_name,'wb')                      
                    f.write(pdf_data.content)                       
                    f.close()
    
        elif len(date_and_sides) == 1:
            if not os.path.exists(month_day):
                os.mkdir(month_day)
            if readings!=[]:#readings
                readings = str(readings[0])
                readings = BeautifulSoup(readings, 'html.parser')
                for link in readings.find_all('a'):
                    pdf_link = link.get('href')
                    if 'http' not in pdf_link:
                        break
                    elif 'openreview' in pdf_link:
                        pdf_link = pdf_link.replace('forum', 'pdf')
                    elif 'arxiv' in pdf_link and 'pdf' not in pdf_link:
                        pdf_link = pdf_link + '.pdf'
                    print(pdf_link)
                    pdf_name = pdf_link.split('/')[-1]
                    if '.pdf' not in pdf_name:
                        pdf_name = pdf_name.split('=')[-1]+'.pdf'
                    print(pdf_name)
    
                    pdf_data = requests.get(pdf_link, proxies=proxies)
                    f = open(month_day+'/'+pdf_name,'wb')                      
                    f.write(pdf_data.content)                       
                    f.close()
            slides = date_and_sides[1]#slides
            slides = str(slides)
            slides = BeautifulSoup(slides, 'html.parser')
            for link in slides.find_all('a'):
                pdf_link = link.get('href')
                print(pdf_link)
                if 'dropbox' in pdf_link and k!=9 and k!=10:#k==9, slide file is in google driver, we don't have access to it;10 file not exits
                    url = 'https://www.dropbox.com/sharing/fetch_user_content_link'
                    cookies = {'__Host-ss':'bcD4Chza3M', 'locale':'zh_CN', 'gvc':'MTQxMzI3NDU0NjU2NzAyODExNDM4MzQ3NTk2NDExMjgyNjc2MzI2', 't':'-VB7vYgNnBuMG3LhS_GfEzTL', '__Host-js_csrf':'-VB7vYgNnBuMG3LhS_GfEzTL', 'seen-sl-signup-modal':'VHJ1ZQ%3D%3D', 'seen-sl-download-modal':'VHJ1ZQ%3D%3D'}
                    data={
                        'is_xhr': 'true',
                        't': '-VB7vYgNnBuMG3LhS_GfEzTL',
                        'url': pdf_link
                    }
                    slide_data = requests.post(url, data=data, proxies = proxies, cookies = cookies)
                    middle_url = str(slide_data.content)
                    print(middle_url)
                    middle_url = middle_url.split('?')[0]
                    middle_url = middle_url[2:]
                    data_2={
                        '_download_id':'013885563736029338651059959499724834269999834692877836324471532568',
                        '_notify_domain':'www.dropbox.com',
                        'dl':'1'
                    }
                    pdf_data = requests.get(middle_url, data=data_2, proxies = proxies)
                    pdf_name = pdf_link.split('/')[-1]
                    pdf_name = pdf_name.split('?')[0]
                    print(pdf_name)
                    f = open(month_day+'/'+pdf_name,'wb')                      
                    f.write(pdf_data.content)                       
                    f.close()
    
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值