用python Beautiful soup爬取OpenJudge網站,並將數據保存在JSON格式內

import requests
import os
import json
from bs4 import BeautifulSoup
headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
    # 'Cookie': '填入自己的Cookie',
    'Host': 'noi.openjudge.cn',
    'Referer': 'http://noi.openjudge.cn/auth/login/'
}
message = {}
def GetText(url):
    """爬取網頁源代碼

    :param url: 網頁的URL
    :return: 返回網頁源碼文本
    """
    try:
        r=requests.get(url, headers = headers)
        r.encoding = r.apparent_encoding
        r.raise_for_status()
        print("響應狀態碼:", r.status_code)
        return r.text
    except Exception as result:
        print("無法訪問: %s" % result)
        return ''

def GetTitleUrl(TitleText):
    """ 獲取標題名字及其URL

    :param TitleText: 網頁源碼文本
    :return: 返回總標題數
    """
    soup = BeautifulSoup(TitleText, 'lxml')
    title_url = soup.find_all('li', class_ = 'practice-info')
    count = 1
    for each in title_url:
        # print(each.a['href'])
        # print(each.a.string)
        # print('*' * 30)
        value = {
            count: {
                'URL': 'http://noi.openjudge.cn' + each.a['href'],
                'Title': each.a.string
            }
        }
        message.update(value)
        count += 1
    return count

def GetQuesUrl(QuesTotalText, cnt):
    """ 爬取每個標題裏的每個問題的題目和題目的URL

    :param QuesTotalText: 標題的網頁源碼文本
    :param cnt: 標題號
    """
    soup = BeautifulSoup(QuesTotalText, 'lxml')
    ques_url = soup.find_all('td', class_='title')
    for count in range(1, len(ques_url)):
        try:
            # print(ques_url[count].a['href'])
            # print(ques_url[count].a.string)
            # print('*' * 30)
            value = {
                count:{
                    'ques_url': 'http://noi.openjudge.cn' + ques_url[count].a['href'],
                    'ques_name': ques_url[count].a.string
                }
            }
            message[cnt].update(value)
        except Exception as result:
            print('錯誤忽略:', result)
    # pprint(message)

def SaveToCsv():
    path = '../content/openjudge/'
    if not os.path.exists(path):
        os.makedirs(path)
    with open(file=path+'data.json', mode='w', encoding='utf-8') as fp:
        json.dump(obj=message, fp=fp, ensure_ascii=False)


def main():
    url = 'http://noi.openjudge.cn/'
    TitleText = GetText(url)
    count = GetTitleUrl(TitleText)
    for num in range(1, count + 1):
        try:
            URL = message[num]['URL']
            QuesTotalText = GetText(URL)
            GetQuesUrl(QuesTotalText, num)
        except Exception as result:
            print('Error: ', result)
    SaveToCsv()


    # pprint(TitleText)



if __name__ == '__main__':
    main()
"""
現在已經爬取到了每個問題的URL,並存放在了字典裏。
接下來需要爬取每個問題裏的具體內容。
描述、輸入、輸出、樣式輸入、樣式輸出、提示
統計數據:
全局題號、添加於、提交次數、嘗試人數、通過人數。
message = {
    '標題序號': {
        '標題URL': '標題URL',
        '標題名字': '標題名字',
        '題目序號': {
            '題目URL': '題目URL',
            '題目名字': '題目名字',
            '描述': '描述',
            '輸入': '輸入',
            '輸出': '輸出',
            '樣式輸入': '樣式輸入',
            '樣式輸出': '樣式輸出',
            '提示': '提示',
            '統計數據':{
                '全局題號': '全局題號',
                '添加於': '添加於',
                '提交次數': '提交次數',
                '嘗試人數': '嘗試人數',
                '通過人數': '通過人數'
            }
        }
    }
}
"""
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章