python爬蟲爬取微博之戰疫情用戶評論及詳情


爬取結果下載: https://www.lanzous.com/i9fg9mb

1、爬取具體動態的內容及評論

1.1、分析網頁

微博網址: https://m.weibo.cn/
進入微博後,點擊《戰疫情》主題下,並隨便選擇一個動態進行分析,我就選擇了“央視新聞網”的一條動態https://m.weibo.cn/detail/4471652190688865進行分析。

建議: 選擇的目標評論數量不要太多,評論太多的話分析起來比較費時,還有就是要儘量接近頂部,也不能太少,不然會導致分析不夠全面。最好選擇較新的文章,這樣到首頁獲取它的URL分析時較爲容易。

1.1.1、檢查網頁

把鼠標挪到網頁任意地方,單擊鼠標右鍵,選擇檢查,如圖所示:
在這裏插入圖片描述

1.1.2、元素點位

方法一:把鼠標放在你需要查看的文字上,重新單擊鼠標右鍵,進行檢查
方法二:點擊檢查框左上角的箭頭,移動鼠標直接點擊文字進行定位
在這裏插入圖片描述
通過不斷的進行定位分析,可以發現我們需要的內容沒有字體反爬措施,不需要去做額外的工作了。

1.1.3、下拉加載

我們剛打開該話題的時候,它顯示的是187條評論,但是在審查的時候可以看到:
在這裏插入圖片描述
在文章中只有20個 div , 並且每個 div 中裝載一條評論,每個頁面原始就只能顯示20條評論。

當我們把鼠標不斷向下滑動的過程中,網頁元素中的 div 也不斷隨評論的增加而增加,當活動到底部時,所有評論都加載出來了。可以初步判斷該網頁屬於ajax加載類型,所以先就不要考慮用requests請求服務器了。

1.2、如何爬取下拉加載的信息

1.2.1、方法一:抓包

瀏覽器的中的每一條信息的加載都離不開 Network ,這就意味着我們可以通過它來查看網頁加載出來的內容。

抓包的步驟:

  1. 鼠標右擊,打開檢查功能
  2. 選擇Network
  3. 刷新網頁
  4. 查看加載的數據
    在這裏插入圖片描述

如何更好的查看加載的內容是什麼?

我們的目的只是找到自己需要的內容,沒有必要全部都查看一遍,只需要知道一些關鍵的數據進行查看就好了。

  1. 最重要的是注意 Network 中的Type(加載的文件類型) 和 size(加載的文件大小) 這兩個要素,如我們要查看的目標是文字文件,帶有圖片類型的文件都可以不用查看了,其二就是它的大小,上面的很多文件都沒有顯示大小,我們幾乎可以把它忽略了。對於網頁不是很瞭解的同學,不建議直接使用篩選功能。
  2. 查看內容:
    在這裏插入圖片描述
  3. 我們需要的內容疑似在其中,但是text的內容我們並不認識,不用怕,先把它複製,再找個json解析器在線解析一下。如我用這個解析器: https://www.json.cn/ ,把剛纔的內容粘貼進來看看結果
    在這裏插入圖片描述
  4. 看到了吧,這個不就正式我們需要的結果嗎,往下面查看,20條評論都在其中了。
  5. 複製這個路徑,python請求看看:
import requests
import json

reponse = requests.get('https://m.weibo.cn/comments/hotflow?id=4471652190688865&mid=4471652190688865&max_id_type=0')
json.loads(reponse.text)

在這裏插入圖片描述
6. 完美拿到我們需要的數據,接下來就是再去抓其他的數據了,分析一下它們的URL
在這裏插入圖片描述
7. 我們可以看到,它們的不同之處都在 max_id 上,只要找出它們的關係,就可以拿到它的數據啦。
8. 如果它的關係不好找的話,那就換其他的方法爬取吧。
9. 但是,通過Ajax拿到數據纔是最快最全的,所以必須想辦法拿到它的 max_id , 下面第5節有關於它的講解

1.2.2、方法二: selenium庫

這個是開發來做自動化的庫,但是用它來做爬蟲幾乎是無敵的存在,就不多介紹它了,直接開始吧
注意: 如谷歌瀏覽器,這個庫需要配合 chromedriver.exe 來使用,才能控制瀏覽器。可以到 http://npm.taobao.org/mirrors/chromedriver/ 下載對應自己谷歌瀏覽器的版本,如果找不到合適自己谷歌的版本的 chromedriver.exe ,可以下載鄰近版本的試試或者更新谷歌瀏覽器,然後進行相關的配置就好了,也可以直接把下載的 chromedriver.exe 放在Python的安裝環境下,直接調用,前提是python配置過環境變量。當然也可以使用它的路徑來調用。

1.2.2.1、對selenium庫的基本用法認識

  1. 安裝
pip install selenium
  1. 控制瀏覽器
from selenium import webdriver
driver = webdriver.Chrome() #需要調用對應的chromedriver.exe
  1. 使用IP代理,通常不需要都行
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--proxy--server=112.84.55.122:9999')#使用代理IP
  1. 等待網頁加載
driver.implicitly_wait(5) #最長等待5秒,記載完成後自動跳過
  1. 打開網頁
driver.get(url) # 需要打開的網頁
  1. 點擊網頁節點
driver.find_element_by_xpath('這裏放網頁xpath路徑').click()
  1. 輸入內容
driver.find_element_by_xpath('這裏放網頁輸入框的xpath路徑').send_keys('輸入詞')
  1. 獲取文本
driver.find_element_by_xpath('網頁中文本xpath路徑').text #直接獲取某個具體文本
  1. 網頁下拉
js="var q=document.documentElement.scrollTop=10000000" #滾動條,數值爲每次下拉的長度,不疊加,以瀏覽器底部爲最大值
driver.execute_script(js)#調用js
  1. 獲取HTML源碼
driver.page_source

1.2.2.2、認識xpath

xpath 可以理解成網頁上的節點,由 html 的標籤構成,可以進行具體定位,也可以模糊定位,使用起來很靈活。
如何獲取網頁節點的xpath:

  1. 百度爲例,打開百度
  2. 鼠標右擊——>檢查
  3. 定位元素節點
  4. 在HTML源碼上鼠標右擊——> copy ——> Copy Xpath

在這裏插入圖片描述

1.2.2.3、爬取實戰思路

  1. 控制瀏覽器打開網頁
  2. 獲取評論數量:
    • 如果評論量大於20,就需要進行下拉加載,小於20不需要下拉,下拉次數 = 評論數 ÷ 20
    • 但是這裏需要下拉時需要登錄才能繼續加載,先手動QQ登錄一下驗證代碼的可行性
  3. 獲取源碼
  4. 使用解析庫提取信息
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from lxml import etree
import time,random

url = 'https://m.weibo.cn/detail/4471652190688865'
driver = webdriver.Chrome()
driver.implicitly_wait(5)
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--proxy--server=112.84.55.122:9999')#使用代理IP
driver.get(url)#打開網頁網頁
driver.implicitly_wait(6)#等待加載六秒

#獲取評論數
comment_number = driver.find_element_by_xpath('//div[@class="lite-page-tab"]/div[2]/i[2]').text
print ("一共有%s條評論"%comment_number)
if int(comment_number) > 20: #低於20條的評論不用下拉加載
    comment_number = int(int(comment_number) / 20) #每次下拉都加載20條評論
    js="var q=document.documentElement.scrollTop=10000000" #滾動條
    for i in range(comment_number):
        driver.execute_script(js)#調用js,將頁面拖到底
        time.sleep(random.uniform(0, 1.2)) #暫停時間:0~1.2秒
        if i == 1:
            time.sleep(10) #暫停10秒,手動一鍵登錄
source = driver.page_source
html_etree = etree.HTML(source)
#爬取主題文字
title = html_etree.xpath('//div[@class="weibo-text"]/text()')[0]

# 獲取所有評論
div_item = html_etree.xpath('//*[@id="app"]/div[1]/div/div[3]/div[2]/div')
for item in div_item:
    try:
        comments = item.xpath('./div/div/div/div/div[2]/div[1]/div/div/h3/text()')[0]
    except:
        pass
    print(comments)

輸出結果:

一共有282條評論

2月都不需要統計了
經濟大環境本來就不好,錢都套在房子裏,到處在裁員,這會班都上不了,哪有錢買車哦
汽車行業雪上加霜。
家裏車放了半個多月了~放那就是貶值,艹
人都出不去 難不成網購
錢都買房子了!天天還房貸,房地產是罪魁禍首!
汽車行業1819那兩年本來就已經很不景氣了,今年加上這個疫情,估計後面幾個月也高不到哪裏去
疫情發生有的人生存都成問題,還買車
預計下2月份的唄??
疫情過來,我要買車
經濟損失太大了
車不車的就不考慮了,2020年目標就一個“好好活着”就行。
大家關注一下
因爲武漢政府的不作爲,讓攜帶病毒的人逃竄到各個地方,全國都停工在家,毫無生產力,一起喫國家老本兒!倘若當初他們能提早隔離病患,提早警示,哪怕後來迅速封城,我們都不至於此!全國其他省市都能復工,共同撐起大經濟,醫療防護也不會短缺,這次疫情,經濟上我們恐怕要緩上很長一段時間!
還有搖號、限號,無語了
......

接下來必須解決掉賬號登錄的問題,如果一直用QQ登錄,爬取大量的信息,到時候被封號了就得不償失了,先去註冊一個微博的賬號,直接使用它登錄。
在這裏插入圖片描述


2、實現微博登錄賬號

  • 爲什麼要登陸?
    先用微博賬號登錄我控制的瀏覽器,這樣它就自帶cookie值了,然後再去訪問其他的動態,它就不會再提示讓你去登錄了。
    微博登錄入口: https://passport.weibo.cn/signin/login

2.1、分析網頁

  1. 賬號 id = “loginName”
  2. 密碼 id = “loginPassword”
  3. 登錄 id = “loginAction”
    在這裏插入圖片描述

2.2、實現登錄思路

  1. 通過 id 找到賬號框和密碼框分別輸入賬號和密碼,再點擊登錄
  2. 接下來它會跳轉到驗證碼。它是三種隨機的驗證碼,分別爲滑動條,滑塊,點擊文字,做起來比較複雜,這裏先不管驗證碼,讓代碼暫停一會兒,進行手動驗證吧。

2.3、登錄模塊源碼

from selenium import webdriver
import time
url = 'https://passport.weibo.cn/signin/login'
driver = webdriver.Chrome()
driver.implicitly_wait(5)
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--proxy--server=112.84.55.122:9999')#使用代理IP

driver.get(url)#打開網頁網頁
driver.find_element_by_id('loginName').send_keys('賬號') #輸入賬號
driver.find_element_by_id('loginPassword').send_keys('密碼') #輸入密碼
time.sleep(1)
driver.find_element_by_id('loginAction').click()
#暫停一會兒,手動驗證碼
time.sleep(15)

3、首頁具體動態鏈接獲取

3.1、怎樣尋找Ajax加載的數據

對於這樣的網頁,如何獲取它文章的鏈接也是一個難題,它的這些數據都是通過Ajax動態加載的。從微博的官網,點擊到《戰疫情》主題,發現它的URL並沒有變化,如果通過 selenium 點擊轉到《戰疫情》獲取網頁HTML,找遍怎麼網頁都沒有鏈接,這是就不是 selenium 獲取HTML能搞定的了,還是通過抓包吧,具體方法見 1.2.1、方法一:抓包 :

在這裏插入圖片描述
具體瀏覽幾篇文章後發現,它的的部分 URL 都是統一的,文章鏈接 = 'https://m.weibo.cn/detail/'+ 發佈時的id ,可以通過剛找到的 id 在瀏覽器中拼接試試
在這裏插入圖片描述
恭喜,沒有毛病,成功的找出了它的鏈接規律了!!!

接下來就是獲取它下一個加載數據的通道了,照樣是通過抓包的方式獲取,不斷的下拉網頁,加載出其他的Ajax數據傳輸通道,再進行對比
在這裏插入圖片描述
可以很明顯的看出,它的當前鏈接就只是帶上了&page=當前數字 的標籤,並且每次加載出18篇動態文章
在這裏插入圖片描述

3.2、怎麼解析美化json數據

現在我們拿到的數據是json格式,再提取信息前需要把 str文本 轉化爲json數據,進行查找
可以使用json庫查看它的結構 ,也 可以在線json解析 查看它的結構,更推薦在線解析,方法結構比較清晰
方法一:json.loads()
在這裏插入圖片描述

  • python格式化的包 pprint 也可以直接美化它

方法二:在線解析
結構把結果複製到在線解析網頁中就可以查看結果啦,上面 1.2.1、方法一:抓包 講過方法

3.3、怎麼提取json數據

在線解析後的結果,簡單的給它打上標籤,每一個等級爲一塊,一級包括二級和三級,二級包括三級… 然後通過前面的標籤進行迭代輸出,索引出來
在這裏插入圖片描述
方法實現:

import requests
api_url = 'https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059'
reponse = requests.get(api_url)
for json in reponse.json()['data']['statuses']:
    comment_ID = json['id']
    print (comment_ID)

在這裏插入圖片描述
然後把拿到的id加在https://m.weibo.cn/detail/ 的後面就可以訪問具體的文章了

3.4、提取所有鏈接代碼彙總

import requests,time
from fake_useragent import UserAgent

comment_urls = []
def get_title_id():
    '''爬取戰疫情首頁的每個主題的ID'''
    for page in range(1,3):# 這是控制ajax通道的量
        headers = {
            "User-Agent" : UserAgent().chrome #chrome瀏覽器隨機代理
        }
        time.sleep(2)
        # 該鏈接通過抓包獲得
        api_url = 'https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=' + str(page)
        print (api_url)
        rep = requests.get(url=api_url, headers=headers)
        for json in rep.json()['data']['statuses']:
            comment_url = 'https://m.weibo.cn/detail/' + json['id']
            print (comment_url)
            comment_urls.append(comment_url)
get_title_id()

輸出結果:

https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=1
https://m.weibo.cn/detail/4472725286834498
https://m.weibo.cn/detail/4472896510211624
https://m.weibo.cn/detail/4472846892243445
https://m.weibo.cn/detail/4472901455185821
https://m.weibo.cn/detail/4472856669039437
https://m.weibo.cn/detail/4472897055545751
https://m.weibo.cn/detail/4472891342667233
https://m.weibo.cn/detail/4472879381479272
https://m.weibo.cn/detail/4472889565122923
https://m.weibo.cn/detail/4472884950738226
https://m.weibo.cn/detail/4472883461527008
https://m.weibo.cn/detail/4472904014106917
......

現在成功的拿到了每個文章的鏈接,接下來可以使用 selenium 控制瀏覽器 進行爬蟲了

4、selenium爬取評論

如果對它不熟悉,可以先看看它的文檔,也可以在上面1.2.2.1、對selenium庫的基本用法認識 瞭解它的基本用法。

實戰思路:

  1. 自定義瀏覽器
  2. 登錄微博,讓瀏覽器記錄cookie值
  3. 通過ajax獲取文章鏈接
  4. 分別訪問每篇文章
  5. 通過評論數判斷下拉次數,進行下拉加載數據
  6. 下拉完成後就獲取源碼
  7. 解析網頁提取信息
  8. 保存數據
import requests,json,time,random
from fake_useragent import UserAgent
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from lxml import etree

startTime = time.time() #記錄起始時間
driver = webdriver.Chrome()
driver.implicitly_wait(5)
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--proxy--server=112.84.55.122:9999')#使用代理IP

fileName = "./微博戰疫情.txt"
comment_urls = [] #盛放每個動態的鏈接

def login_weibo():
    '''登錄微博,獲取cookie值'''
    login_url = 'https://passport.weibo.cn/signin/login'
    driver.get(login_url)#打開網頁網頁
    driver.find_element_by_id('loginName').send_keys('13985968945')
    driver.find_element_by_id('loginPassword').send_keys('ayouleyang')
    time.sleep(1)
    driver.find_element_by_id('loginAction').click()
    time.sleep(20)#驗證碼,需要自己動手驗證

def get_title_id():
    '''爬取戰疫情首頁的每個主題的ID'''
    for page in range(1,11):
        headers = {
            "User-Agent" : UserAgent().chrome #chrome瀏覽器隨機代理
        }
        time.sleep(2)
        # 該鏈接通過抓包獲得
        api_url = 'https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=' + str(page)
        print (api_url)
        rep = requests.get(url=api_url, headers=headers)
        for json in rep.json()['data']['statuses']:
            comment_url = 'https://m.weibo.cn/detail/' + json['id']
            comment_urls.append(comment_url)
#             print (comment_url)
            
def spider_comments():
    '''爬取所有評論並保存'''
    comment_url_sum = len(comment_urls)
    js="var q=document.documentElement.scrollTop=10000000" #滾動條
    for count,comment_url in enumerate(comment_urls):        
        driver.get(comment_url)
        driver.implicitly_wait(5)
        try:
            #獲取評論
            comment_number = driver.find_element_by_xpath('//div[@class="lite-page-tab"]/div[2]/i[2]').text
            print ("正在爬取第%s個話題,該話題包括%s條評論,總共有%s個話題"%(count+1, comment_number,comment_url_sum))
            if int(comment_number) > 20: #低於20條的評論不用下拉加載
                comment_number = int(int(comment_number) / 20) #每次下拉都加載20條評論
                for i in range(comment_number):
                    driver.execute_script(js)#調用js,將頁面拖到底
                    time.sleep(random.uniform(0, 1.2)) #暫停時間:0~1.2秒
            source = driver.page_source
            html_etree = etree.HTML(source)
            #爬取主題文字
            title = html_etree.xpath('//div[@class="weibo-text"]/text()')[0]
            with open(fileName,'a', encoding='utf-8') as f:
                f.write(title)
                f.close()
            # 獲取所有評論
            div_item = html_etree.xpath('//*[@id="app"]/div[1]/div/div[3]/div[2]/div')
            for item in div_item:
                try:
                    comments = item.xpath('./div/div/div/div/div[2]/div[1]/div/div/h3/text()')[0]
                    # 保存數據
                    with open(fileName,'a', encoding='utf-8') as f:
                        f.write(str(comments))
                        f.close()
                except:
                    pass
        except:
            print ("該頁面無法查看")
if __name__ == '__main__':
    login_weibo()
    get_title_id()
    spider_comments()
    endTime =time.time()#獲取結束時的時間
    useTime =(endTime-startTime)/60
    print ("該次所獲的信息一共使用%s分鐘"%useTime)

5、requests ajax 爬取更多信息

目標:話題鏈接、話題內容、樓主ID、樓主暱稱、樓主性別、發佈日期、發佈時間、轉發量、評論量、點贊量、評論者ID、評論者暱稱、評論者性別、評論日期、評論時間、評論內容

現在我需要獲取更多的信息,如用戶id, 性別之類的,這就不是selenium可以完成的操作了,還得使用ajax的方式獲取json數據,提取詳細的信息;如果您看了1.2.1、方法一:抓包 ,相信也幾乎明白了,上面遺留的 max_id 問題,其實找到這個也不難,始終堅信計算機數據不可能無中生有,一定是在某地我們沒有找到。果不其然,它就在上一個json文件底部。

  • 第一個通道
    在這裏插入圖片描述
  • 現在可以預測下一個 max_id
    在這裏插入圖片描述
    成功的通過上一個通道拿到了下一個通道的 max_id ,現在不就可以使用ajax加載數據了嗎

貼上全部代碼

# -*- coding: utf-8 -*-
import requests,random,re
import time
import os
import csv
import sys
import json
import importlib
importlib.reload(sys)
from fake_useragent import UserAgent
from lxml import etree

startTime = time.time() #記錄起始時間
# 存爲csv

path = os.getcwd() + "/weiboComments.csv"
csvfile = open(path, 'a', newline='', encoding = 'utf-8-sig')
writer = csv.writer(csvfile)
writer.writerow(('話題鏈接','話題內容','樓主ID', '樓主暱稱', '樓主性別','發佈日期', '發佈時間', '轉發量','評論量','點贊量', '評論者ID', '評論者暱稱', '評論者性別', '評論日期', '評論時間','評論內容')) #csv頭部

headers = {
    'Cookie': '_T_WM=22822641575; H5_wentry=H5; backURL=https%3A%2F%2Fm.weibo.cn%2F; ALF=1584226439; MLOGIN=1; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9W5RJaVYrb.BEuOvUQ8Ca2OO5JpX5K-hUgL.FoqESh-7eKzpShM2dJLoIp7LxKML1KBLBKnLxKqL1hnLBoMceoBfeh2EeKBN; SCF=AnRSOFp6QbWzfH1BqL4HB8my8eWNC5C33KhDq4Ko43RUIzs6rjJC49kIvz5_RcOJV2pVAQKvK2UbAd1Uh6j0pyo.; SUB=_2A25zQaQBDeRhGeBM71cR8SzNzzuIHXVQzcxJrDV6PUJbktAKLXD-kW1NRPYJXhsrLRnku_WvhsXi81eY0FM2oTtt; SUHB=0mxU9Kb_Ce6s6S; SSOLoginState=1581634641; WEIBOCN_FROM=1110106030; XSRF-TOKEN=dc7c27; M_WEIBOCN_PARAMS=oid%3D4471980021481431%26luicode%3D20000061%26lfid%3D4471980021481431%26uicode%3D20000061%26fid%3D4471980021481431',
    'Referer': 'https://m.weibo.cn/detail/4312409864846621',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest'
}
comments_ID = []
def get_title_id():
    '''爬取戰疫情首頁的每個主題的ID'''
    for page in range(1,21):# 每個頁面大約有18個話題
        headers = {
            "User-Agent" : UserAgent().chrome #chrome瀏覽器隨機代理
        }
        time.sleep(1)
        # 該鏈接通過抓包獲得
        api_url = 'https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=' + str(page)
        print (api_url)
        rep = requests.get(url=api_url, headers=headers)
        for json in rep.json()['data']['statuses']:
            comment_ID = json['id']
            comments_ID.append(comment_ID)
            
def spider_title(comment_ID):
    try:
        article_url = 'https://m.weibo.cn/detail/'+ comment_ID
        print ("article_url = ", article_url)
        html_text = requests.get(url=article_url, headers=headers).text
        # 話題內容
        find_title = re.findall('.*?"text": "(.*?)",.*?', html_text)[0]
        title_text = re.sub('<(S*?)[^>]*>.*?|<.*? />', '', find_title) #正則匹配掉html標籤
        print ("title_text = ", title_text)
        # 樓主ID
        title_user_id = re.findall('.*?"id": (.*?),.*?', html_text)[1]
        print ("title_user_id = ", title_user_id)
        # 樓主暱稱
        title_user_NicName = re.findall('.*?"screen_name": "(.*?)",.*?', html_text)[0]
        print ("title_user_NicName = ", title_user_NicName)
        # 樓主性別
        title_user_gender = re.findall('.*?"gender": "(.*?)",.*?', html_text)[0]
        print ("title_user_gender = ", title_user_gender)
        # 發佈時間
        created_title_time = re.findall('.*?"created_at": "(.*?)".*?', html_text)[0].split(' ')
        #日期
        if 'Feb' in created_title_time:
            title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '02', created_title_time[2])
        elif 'Jan' in created_title_time:
            title_created_YMD = "{}/{}/{}".format(created_title_time[-1], '01', created_title_time[2])
        else:
            print ('該時間不在疫情範圍內,估計數據有誤!URL = ')
            pass
        print ("title_created_YMD = ", title_created_YMD)
        #發佈時間
        add_title_time = created_title_time[3]
        print ("add_title_time = ", add_title_time)
        # 轉發量
        reposts_count = re.findall('.*?"reposts_count": (.*?),.*?', html_text)[0]
        print ("reposts_count = ", reposts_count)
        # 評論量
        comments_count = re.findall('.*?"comments_count": (.*?),.*?', html_text)[0]
        print ("comments_count = ", comments_count)
        # 點贊量
        attitudes_count = re.findall('.*?"attitudes_count": (.*?),.*?', html_text)[0]
        print ("attitudes_count = ", attitudes_count)   
        comment_count = int(int(comments_count) / 20)#每個ajax一次加載20條數據,
        position1 = (article_url, title_text, title_user_id, title_user_NicName,title_user_gender, title_created_YMD, add_title_time, reposts_count, comments_count, attitudes_count, " ", " ", " ", " "," ", " ")
        writer.writerow((position1))#寫入數據   
        return comment_count
    except:
        pass

def get_page(comment_ID, max_id, id_type):
    params = {
        'max_id': max_id,
        'max_id_type': id_type
    }
    url = ' https://m.weibo.cn/comments/hotflow?id={}&mid={}&max_id'.format(comment_ID, comment_ID)
    try:
        r = requests.get(url, params=params, headers=headers)
        if r.status_code == 200:
            return r.json()
    except requests.ConnectionError as e:
        print('error', e.args)
        pass

def parse_page(jsondata):
    if jsondata:
        items = jsondata.get('data')
        item_max_id = {}
        item_max_id['max_id'] = items['max_id']
        item_max_id['max_id_type'] = items['max_id_type']
        return item_max_id

def write_csv(jsondata):
    for json in jsondata['data']['data']:
        #用戶ID
        user_id = json['user']['id']
        # 用戶暱稱
        user_name = json['user']['screen_name']
        # 用戶性別,m表示男性,表示女性
        user_gender = json['user']['gender']
        #獲取評論
        comments_text = json['text']
        comment_text = re.sub('<(S*?)[^>]*>.*?|<.*? />', '', comments_text) #正則匹配掉html標籤
        # 評論時間
        created_times = json['created_at'].split(' ')
        if 'Feb' in created_times:
            created_YMD = "{}/{}/{}".format(created_times[-1], '02', created_times[2])
        elif 'Jan' in created_times:
            created_YMD = "{}/{}/{}".format(created_times[-1], '01', created_times[2])
        else:
            print ('該時間不在疫情範圍內,估計數據有誤!')
            pass
        created_time = created_times[3] #評論時間時分秒
#         if len(comment_text) != 0:
        position2 = (" ", " ", " ", " "," ", " ", " ", " ", " ", " ", user_id, user_name, user_gender, created_YMD, created_time, comment_text)
        writer.writerow((position2))#寫入數據
#         print (user_id, user_name, user_gender, created_YMD, created_time)    
def main():
    count_title = len(comments_ID)
    for count, comment_ID in enumerate(comments_ID):
        print ("正在爬取第%s個話題,一共找到個%s話題需要爬取"%(count+1, count_title))
        maxPage = spider_title(comment_ID) # 評論佔的最大頁數
        print ('maxPage = ', maxPage)
        m_id = 0
        id_type = 0
        if maxPage != 0: #小於20條評論的不需要循環
            try:
                for page in range(0, maxPage):#用評論數量控制循環
                    jsondata = get_page(comment_ID, m_id, id_type)
                    write_csv(jsondata)
                    results = parse_page(jsondata)
                    time.sleep(1)
                    m_id = results['max_id']
                    id_type = results['max_id_type']              
            except:
                pass
        print ("--------------------------分隔符---------------------------")
    csvfile.close() 
    
if __name__ == '__main__':
    get_title_id()
    main()
    endTime =time.time()#獲取結束時的時間
    useTime =(endTime-startTime)/60
    print ("該次所獲的信息一共使用%s分鐘"%useTime)

編輯器運行結果:

https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=1
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=2
......
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=18
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=19
https://m.weibo.cn/api/feed/trendtop?containerid=102803_ctg1_600059_-_ctg1_600059&page=20
正在爬取第1個話題,一共找到個361話題需要爬取
article_url =  https://m.weibo.cn/detail/4472132886924452
title_text =#鍾南山院士指導研發快速檢測試劑盒# #採一滴血15分鐘內可獲檢測結果#】昨天,呼吸疾病國家重點實驗室對外透露,近日,在鍾南山院士的指導下,實驗室聯合多家研究機構,最新研發出新型冠狀病毒IgM抗體快速檢測試劑盒,並已在實驗室和臨牀完成初步評價。據介紹,僅需採取一滴血就可在15分鐘內肉眼觀察獲得檢測結果,且患者的血漿稀釋500至1000倍後,仍能檢測出陽性條帶。呼吸疾病國家重點實驗室表示,這一試劑盒在湖北某醫院進行了應用試驗。通過對部分臨牀已確診爲新型冠狀病毒感染陽性(但PCR核酸檢測陰性的)患者血樣進行復檢,該試劑盒能檢出相當部分(IgM)陽性,提示可與核酸檢測形成互補。目前該試劑盒(科研用)樣品已大批送至湖北省武漢市、黃岡市、大冶市等地基層衛生機構等,與核酸檢測等技術聯合用於檢測新型冠狀病毒感染的測試評估。(總檯央視記者陳旭婷)
title_user_id =  2656274875
title_user_NicName =  央視新聞
title_user_gender =  m
title_created_YMD =  2020/02/15
add_title_time =  07:30:31
reposts_count =  3094
comments_count =  2419
attitudes_count =  33365
maxPage =  120
--------------------------分隔符---------------------------
正在爬取第2個話題,一共找到個361話題需要爬取
article_url =  https://m.weibo.cn/detail/4472213728267581
title_text =#新冠病毒疫苗研發已完成基因序列合成#】2月15日中國醫藥集團有限公司在京披露,該集團與中國疾病預防控制中心合作,新型冠狀病毒疫苗的研發已經取得進展。國藥集團旗下的國藥中生研究院啓動了新型冠狀病毒基因工程疫苗研發,現已完成了基因序列合成,正在進行重組質粒構建和工程菌篩選工作。國藥集團方面進一步介紹,目前國藥集團正在多路出擊,攻堅新冠病毒疫苗的研發。其中國藥中生武漢公司也擔負着新型冠狀病毒疫苗的研發任務,目前正在持續進行病毒培養。國藥中生北京公司則與中國疾病預防控制中心緊密合作,正在開發新型冠狀病毒滅活疫苗,目前正在進行毒種庫的建庫工作。據介紹,研究發現在新冠康復者血漿中,有着豐富的新型冠狀病毒綜合抗體。爲此,國藥中生在研究中還提出了“用新冠康復者血漿治療危重患者”的建議,並已獲得科技部緊急立項。目前國藥中生已按照國家衛健委和國家藥監局的標準制備了新冠康復者血漿,並用於11名危重病人治療。在使用“血漿療法”後,截至目前所有治療的危重病人未發生任何不良反應,各項重要檢測指標全面向好。其中一位86歲危重患者應用此治療方案後,臨牀體徵和症狀已經獲得了明顯改善。現在國藥中生又開始用新冠康復者血漿治療另外12例危重患者,併發出公開倡議,呼籲能有更多的新冠康復者獻出自己的一份血漿。同時國藥集團方面表示,新冠康復者獻出的血漿將接受呼吸道、消化道以及其他傳染病等30多種致病病原體的檢測,隨後這一血漿也將接受滅活處理,所以能保障患者的安全使用。當日在武漢大學人民醫院的獻血屋內,國藥集團的工作人員在現場連線時介紹,目前已有20多人提出明確的捐贈意向,昨天這一獻血屋已成功採集了3位康復者的血漿,今天則有5人預計將來現場獻出自己的血漿。另外經過緊急擴產,國藥集團所屬中生捷諾的新冠病毒診斷試劑盒產能目前已經放大到每天20萬人份。(北京日報客戶端)
title_user_id =  1618051664
title_user_NicName =  頭條新聞
title_user_gender =  f
title_created_YMD =  2020/02/15
add_title_time =  12:51:45
reposts_count =  321
comments_count =  180
attitudes_count =  1756
maxPage =  9
--------------------------分隔符---------------------------
正在爬取第3個話題,一共找到個361話題需要爬取
.......

保存數據截圖:
在這裏插入圖片描述

這個代碼還可以進行優化,比如 spider_title(comment_ID) 模塊,也可以使用ajax加載,在 3、首頁具體動態鏈接獲取 中就有關於這個方法的介紹,它的信息全部在這個json文件中,直接提取出來就行啦,這裏就不多介紹了~

萬衆一心,衆志成城,全民抗擊疫情,在家裏也不要忘記學習哈,中國加油,武漢加油!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章