2017年6月1日 星期四

Python邊學邊記錄-Crawler網路爬蟲-第六課-PTT文章爬取

Python Crawler

ptt的sex版,每日每夜都有廢文產生,有時候沒有跟到的話,就只能500P求圖!
這時候就可以放著自動去爬了..

透過網頁版去登入的時候會發現,需要滿18才可以進去!
Python Crawler

這時候可以透過開發工具發現,client端送了一個cookie『over18=1』給了server!
Python Crawler

所以我們就可以利用這點來讓server相信,我們滿18了!
我們在透過requests.get的時候,就可以送個訊息給server端了:
resp = requests.get(
    url=url,    cookies={'over18': '1'}
)

再來就是要先確認,我們需要那些資訊!
Python Crawler

流程的部份:
我們登入首頁(此時是最新文章)->記錄上頁連結->確認有無本日文章->回到上頁->確認有無本日文章...如此迴圈!
PYTHON crawler
需求套件:
import requests
import time
import json
from bs4 import BeautifulSoup

公用變數:
ptt_url = 'https://www.ptt.cc' # 保留以後可以變數帶入其它板的機會

主程式的部份:

def __name__ == '__main__':
    connect_page =  checkStatus(ptt_url + '/bbs/sex/index.html') #確認網頁狀態是否正常
if connect_page:
        articles = [] #用來記錄文章list
        today = time.strftime("%m/%d").lstrip('0') #今天日期格式調整,time是import的模組
        today_articles,pre_url = get_articles(connect_page,today) #呼叫爬蟲fucntion
        # 到上面,已經可以爬到主頁上的文章了!
        # 爬完了之後,要進入驗證的迴圈,確認有無其它本日文章!
        while today_articles: #確認有無本日文章,如果list回來已經沒有東西了,那就代表沒有了!
            articles += today_articles #把爬回傳的list先寫丟進去主list
            connect_page = checkStatus(pre_url) #一樣需要做網頁狀態驗證
            today_articles,pre_url = get_articles(connect_page,today) #再呼叫爬蟲!







checkStatus(url):
# 主要確認網頁是否正常
def checkStatus(url):
    resp = requests.get(
        url = url,
        cookies = {'over18':'1'}
    )
    if resp.status_code != 200: #如果網頁狀態不存活了,就直接return None
        return None
    else:
        return resp.text

get_articles():
# 資料爬取的主要程式
def get_articles(respText,date): #一個是resp拋過來的資料,一個是今日的日期。
    soup = BeautifulSoup(respText,'html5lib')
    #取得網頁的上頁連結
    pre_div = soup.find('div','btn-group btn-group-paging')
    pre_url = pre_div.find_all('a')[1].href
    
    articles = [] #用來記錄文章list
    divs = soup.find_all('div','r-ent') #ptt的文章,都放在class是r-ent上!
    for d in divs:
        if d.find('div','date').text.strip() == date: #確認日期跟今天的日期是否相同
            #取得推文數
            pushCount = 0
            pushStr = d.find('div','nrec').text
            #因為推文有時候會是『X』被噓爆,或是『爆』被推爆,所以要特別處理。
            if pushStr:
                try:
                    pushCount = int(pushStr) #字串轉數字
                except ValueError:
                    if pushStr =="爆":
                        pushCount=99
                    elif pushStr.startswith('X'):
                        pushCount=-10

            #取得文章連結跟標題
            #這邊可以依需求自取,甚至可以再另外寫一個function去爬發文者的ip來做記錄!
            #後面可以利用那發文ip來比對id,就知道誰有什麼分身了...
            if d.find('a'): #有超連結就代表文章還活著,沒有被d掉。
                href = d.find('a').href #連結
                articleTitle = d.find('a').text #標題
                author = ''
                articles.append({
                    'title':articleTitle,
                    'href':href,
                    'author':author,
                    'pushCount':pushCount
                })
    return articles,pre_url

以上!
後續再來加追去取得發文者ip!



沒有留言:

張貼留言