美文网首页
手把手教你批量下载PDF数据报告

手把手教你批量下载PDF数据报告

作者: c9af2eadd50d | 来源:发表于2017-09-28 23:18 被阅读1312次

    有些时候我们需要查看一些数据报告,而某些网站又提供下载地址,但是分页又比较多,一页一页下载太花时间,所以写个爬虫批量将所有PDF文件下载下来。接下来将从Talkdata上批量下载所有的PDF数据报告。

    分析网址

    首先,找到Talkdata数据报告下载地址:http://mi.talkingdata.com/reports.html,从页面上可以看到左侧有报告的分类,中部则是报告地址,而底部有分页按钮。这里需要先获取分类的链接地址,然后逐页获取报告地址,再通过报告下载地址下载PDF文件。通过查看发现“提交并下载此报告”按钮含有报告下载地址,不需要经过跳转,但前端页面正常下载则需提交姓名、公司、邮箱及手机号才可点击提交。

    数据报告页面 报告页面 报告下载地址

    构建爬虫

    获取所有的分类地址
    先请求数据报告页面,解析获得分类链接地址,并过滤掉“全部资源”的链接避免重复。前面先导入所有需要使用到的相关库,request用于请求URL页面,time用来延时避免访问过快,urllib.request用于下载PDF文件,BeautifulSoup解析文本,count构建迭代器。get_category_urls最终返回存放所有分类链接地址的列表。

    import requests
    import time
    import urllib.request
    from bs4 import BeautifulSoup
    from itertools import count
    
    
    def get_category_urls():
        """获取所有的分类链接"""
        category_urls = []  # 存放分类链接地址
        url = 'http://mi.talkingdata.com/reports.html'
        response = requests.get(url)
        soup = BeautifulSoup(response.text, 'lxml')
        categorys = soup.select('div.report-left > ul > li > a')  # 获取分类标签元素
    
        for category in categorys:
            category_name = category['title']  # 分类名称
            category_url = category['href']  # 分类链接
            # 排除“全部”
            if category_url.split('=')[-1] != 'all':
                category_urls.append(category_url)
    
        return category_urls
    

    获取所有的报告地址
    因为多分类和多页的原因,这里为了使爬虫更加清晰简单,将使用两个函数来获取所有的报告地址。先构获取单一分类下所有页码的报告地址,再获取每一个分类下的所有报告地址。get_category_pages函数将从第一页开始遍历,直到当页面链接下获取的报告地址元素列表为空的时候断开循环。在每次循环获取页码页面的地方添加time.sleep进行延时操作。get_report_urls函数遍历分类链接列表,传入get_category_pages,最后添加到存在所有报告链接的列表中。

    def get_report_urls(category_urls):
        """"获取所有分类下的报告链接"""
        all_report_urls = []  # 存放所有报告URL地址
    
        for category_url in category_urls:
            category_report_urls = get_category_pages(category_url)
            all_report_urls.extend(category_report_urls)
    
        return all_report_urls
    
    
    
    def get_category_pages(category_url):
        """获取一个分类下所有页码的报告链接"""
        category_report_urls = []  # 存放分类下所有页码的报告链接
    
        # 从第一页开始遍历,当获取的报告列表为空时,即最后一页之后停止
        for page in count(1):
            start_url = category_url + '&tag=all&page=' + str(page)
    
            response = requests.get(start_url)
            soup = BeautifulSoup(response.text, 'lxml')
            books = soup.select('div.operate-book > em > a')
    
            if books:
                for book in books:
                    report_name = book['title']  # 报告名称
                    report_url = book['href']  # 报告链接
                    category_report_urls.append(report_url)
            else:
                break
    
            time.sleep(2)
    

    下载报告PDF文件

    在获取所有的报告链接地址后,需要从报告页面中提取报告下载地址。因下载链接地址含有中文,所以需要使用urllib.request.quote对URL进行编码操作。到了这里基本已经完成爬虫程序,但是还没结束。

    def download_report(report_url):
        """根据报告地址下载PDF文件"""
        response = requests.get(report_url)
        soup = BeautifulSoup(response.text, 'lxml')
        download_link = soup.find('button')['data-url']  # 获取报告下载地址
        file_name = download_link.split('/')[-1]  # PDF文件名
    
        urllib.request.urlretrieve('https://' + urllib.request.quote(download_link[8:]), '{}.pdf'.format(file_name))
    

    爬虫主程序

    前面已经写好所有相关的爬虫函数,最后添加爬虫主程序spider对爬虫函数进行调用,遍历所有的下载链接地址,调用download_report进行下载,这使得整个过程更加清晰明了。运行主程序后等待几十分钟,所有PDF文件均已下载成功。

    def spider():
        """爬虫主程序"""
        category_urls = get_category_urls()
        report_urls = get_report_urls(category_urls)
    
        for report_url in report_urls:
            download_report(report_url)
            time.sleep(2)
    
    
    if __name__ == '__main__':
        spider()
    
    下载好的PDF文件

    相关文章

      网友评论

          本文标题:手把手教你批量下载PDF数据报告

          本文链接:https://www.haomeiwen.com/subject/mazvextx.html