1. 程式人生 > >【爬蟲入門】【正則表示式】【Json】抓取CSDN最新文章

【爬蟲入門】【正則表示式】【Json】抓取CSDN最新文章

爬取csdn文章的JSON資料

資料庫分為關係型資料庫和關係型資料庫,關係型資料庫需要通過建立表與表之間的關係來進行資料的儲存和查詢,比如一對一、一對多、多對多關係,表與表之間的關係比較緊密。而非關係型資料庫中,表與表之間是不存在關聯的,每一個表都是獨立儲存資料的。
mongodb屬於非關係型資料庫,可以在表裡直接儲存字典,所以在儲存資料的時候比較方便。

# 介面請求的規律:每請求一次介面,該介面都會返回一個值shown_offset,這個shown_offset的值會作為下一個介面請求的引數,所以這個引數的值可以從上一個資料接著返回新的資料

# 在第一次請求https://www.csdn.net/nav/newarticles地址的時候,返回的網頁原始碼中預設展示了11條資料,同時又進行了一次介面的請求,介面又載入了10條資料。在返回的網頁原始碼中的url標籤中有一個屬性shown-offset,那麼這個屬性的值就是作為了第一次請求介面的引數使用了。
import json,requests, re
class CSDNSpider(object):
    def __init__(self):
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.12 Safari/537.36'
        }

    def get_article_html(self):
        """
        請求csdn最新文章頁面
        :return:
        """
        article_url = 'https://www.csdn.net/nav/newarticles'
        # 模擬瀏覽器首次載入的整個過程。
        # 請求article_url->提取url標的show-offset屬性->同時利用正則將Html中的資料提取出來->利用shown-offset發起第一次介面請求
        response = requests.get(article_url, headers=self.headers)
        shown_offset = re.findall(re.compile(r'<ul.*?id="feedlist_id" shown-offset="(.*?)">', re.S), response.text)[0]
        print(shown_offset)

        datas = re.findall(re.compile(r'<li class="clearfix" data-type="blog".*?<div class="title">.*?<a.*?>(.*?)</a>.*?<div class="summary oneline">(.*?)</div>',re.S), response.text)
        print(len(datas))
        return shown_offset

    def get_json_data(self, shownoffset):
        api_url = 'https://www.csdn.net/api/articles?type=more&category=newarticles&shown_offset={}'.format(shownoffset)
        json_dict = json.loads(requests.get(api_url, headers=self.headers).text)
        articles = json_dict.get('articles',None)
        print(len(articles))
        shown_offset = json_dict.get('shown_offset',None)
        # 將shown_offset作為下一次介面請求的引數
        # 遞迴呼叫函式本身
        if articles and len(articles) > 0 and shown_offset:
            self.get_json_data(shown_offset)

if __name__ == '__main__':
    csdn = CSDNSpider()
    # 這個shownoffset就是從原始碼中提取的值,用作第一次介面請求
    shownoffset = csdn.get_article_html()
    csdn.get_json_data(shownoffset)