手把手教你批量下載PDF數(shù)據(jù)報(bào)告

有些時(shí)候我們需要查看一些數(shù)據(jù)報(bào)告,而某些網(wǎng)站又提供下載地址,但是分頁又比較多,一頁一頁下載太花時(shí)間,所以寫個(gè)爬蟲批量將所有PDF文件下載下來。接下來將從Talkdata上批量下載所有的PDF數(shù)據(jù)報(bào)告。

分析網(wǎng)址

首先,找到Talkdata數(shù)據(jù)報(bào)告下載地址:http://mi.talkingdata.com/reports.html,從頁面上可以看到左側(cè)有報(bào)告的分類,中部則是報(bào)告地址,而底部有分頁按鈕。這里需要先獲取分類的鏈接地址,然后逐頁獲取報(bào)告地址,再通過報(bào)告下載地址下載PDF文件。通過查看發(fā)現(xiàn)“提交并下載此報(bào)告”按鈕含有報(bào)告下載地址,不需要經(jīng)過跳轉(zhuǎn),但前端頁面正常下載則需提交姓名、公司、郵箱及手機(jī)號(hào)才可點(diǎn)擊提交。

數(shù)據(jù)報(bào)告頁面
報(bào)告頁面
報(bào)告下載地址

構(gòu)建爬蟲

獲取所有的分類地址
先請(qǐng)求數(shù)據(jù)報(bào)告頁面,解析獲得分類鏈接地址,并過濾掉“全部資源”的鏈接避免重復(fù)。前面先導(dǎo)入所有需要使用到的相關(guān)庫,request用于請(qǐng)求URL頁面,time用來延時(shí)避免訪問過快,urllib.request用于下載PDF文件,BeautifulSoup解析文本,count構(gòu)建迭代器。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')  # 獲取分類標(biāo)簽元素

    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

獲取所有的報(bào)告地址
因?yàn)槎喾诸惡投囗摰脑?,這里為了使爬蟲更加清晰簡單,將使用兩個(gè)函數(shù)來獲取所有的報(bào)告地址。先構(gòu)獲取單一分類下所有頁碼的報(bào)告地址,再獲取每一個(gè)分類下的所有報(bào)告地址。get_category_pages函數(shù)將從第一頁開始遍歷,直到當(dāng)頁面鏈接下獲取的報(bào)告地址元素列表為空的時(shí)候斷開循環(huán)。在每次循環(huán)獲取頁碼頁面的地方添加time.sleep進(jìn)行延時(shí)操作。get_report_urls函數(shù)遍歷分類鏈接列表,傳入get_category_pages,最后添加到存在所有報(bào)告鏈接的列表中。

def get_report_urls(category_urls):
    """"獲取所有分類下的報(bào)告鏈接"""
    all_report_urls = []  # 存放所有報(bào)告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):
    """獲取一個(gè)分類下所有頁碼的報(bào)告鏈接"""
    category_report_urls = []  # 存放分類下所有頁碼的報(bào)告鏈接

    # 從第一頁開始遍歷,當(dāng)獲取的報(bào)告列表為空時(shí),即最后一頁之后停止
    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']  # 報(bào)告名稱
                report_url = book['href']  # 報(bào)告鏈接
                category_report_urls.append(report_url)
        else:
            break

        time.sleep(2)

下載報(bào)告PDF文件

在獲取所有的報(bào)告鏈接地址后,需要從報(bào)告頁面中提取報(bào)告下載地址。因下載鏈接地址含有中文,所以需要使用urllib.request.quote對(duì)URL進(jìn)行編碼操作。到了這里基本已經(jīng)完成爬蟲程序,但是還沒結(jié)束。

def download_report(report_url):
    """根據(jù)報(bào)告地址下載PDF文件"""
    response = requests.get(report_url)
    soup = BeautifulSoup(response.text, 'lxml')
    download_link = soup.find('button')['data-url']  # 獲取報(bào)告下載地址
    file_name = download_link.split('/')[-1]  # PDF文件名

    urllib.request.urlretrieve('https://' + urllib.request.quote(download_link[8:]), '{}.pdf'.format(file_name))

爬蟲主程序

前面已經(jīng)寫好所有相關(guān)的爬蟲函數(shù),最后添加爬蟲主程序spider對(duì)爬蟲函數(shù)進(jìn)行調(diào)用,遍歷所有的下載鏈接地址,調(diào)用download_report進(jìn)行下載,這使得整個(gè)過程更加清晰明了。運(yùn)行主程序后等待幾十分鐘,所有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文件
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,733評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,037評(píng)論 4 61
  • 1,寫出 構(gòu)造函數(shù)模式、混合模式、模塊模式、工廠模式、單例模式、發(fā)布訂閱模式的范例。 2,使用發(fā)布訂閱模式寫一個(gè)事...
    進(jìn)擊的前端_風(fēng)笑影閱讀 465評(píng)論 0 1
  • 端午節(jié),現(xiàn)在好像大大小小的節(jié)日都能收到祝福收到紅包,剛剛收了六一節(jié)紅包,殊不知這個(gè)節(jié)日是懷念的日子,我們似乎...
    靜百合YY閱讀 275評(píng)論 0 1

友情鏈接更多精彩內(nèi)容