天天看點

python爬貼吧回複_通過python爬取貼吧資料并儲存為word

前言

Python是一種跨平台的計算機程式設計語言。是一種面向對象的動态類型語言,最初被設計用于編寫自動化腳本(shell),随着版本的不斷更新和語言新功能的添加,越來越多被用于獨立的、大型項目的開發。

日前,在學習中思考,如何整理一份貼吧曆史資料出來,從中找尋當年玩貼吧的回憶呢。

于是就有了想從貼吧爬取資料的想法,此代碼的由來就是如此。

事前準備

應先安裝pycharm,此處使用的是社群版用于個人學習。如商業行為請支援正版pycharm套件。

檢查需求

擷取貼吧清單的真實連結

分析鎖定回複量為篩選值,篩選出指定回複量以上的文章

将指定文章的URL導出為表格形式儲存

通過URL讀取文章資料,儲存一樓資料并存為word檔案命名為文章名(前5個字元).docx

開工

特别注意本文使用的是python3.7,無法直接從pycharm中add進docx包,否則會報錯,請務必使用手動下載下傳安裝,原因及解決方法如下

解決方法:

1.指令行 解除安裝docx,pip uninstall docx

2.下載下傳 python_docx-0.8.10-py2.py3-none-any.whl 下載下傳位址

3. 指令行輸入pip install python_docx-0.8.10-py2.py3-none-any.whl使用新的docx包

檔案名應與下載下傳的時候一緻,也許之後會再進行更新

代碼部分

擷取連結模闆及輸出貼吧清單

打開浏覽器,按下F12,打開貼吧,搜尋一個貼吧,這邊以"希靈帝國"為例

打開後可以看到,該帖吧首頁的位址是:https://tieba.baidu.com/f?ie=utf-8&kw=%E5%B8%8C%E7%81%B5%E5%B8%9D%E5%9B%BD&fr=search

通過浏覽器的翻譯,我們可以得知:希靈帝國被浏覽器翻譯成%E5%B8%8C%E7%81%B5%E5%B8%9D%E5%9B%BD,是以這串其實就是希靈帝國四個字的unicode顯示,是以得出了貼吧名字在貼吧連結裡占用的子產品。

該貼吧第四頁的位址是:https://tieba.baidu.com/f?kw=%E5%B8%8C%E7%81%B5%E5%B8%9D%E5%9B%BD&ie=utf-8&pn=150

重新點回第一頁:https://tieba.baidu.com/f?kw=%E5%B8%8C%E7%81%B5%E5%B8%9D%E5%9B%BD&ie=utf-8&pn=0

點第二頁:https://tieba.baidu.com/f?kw=%E5%B8%8C%E7%81%B5%E5%B8%9D%E5%9B%BD&ie=utf-8&pn=50

得出規律:https://tieba.baidu.com/f?kw=貼吧名字&ie=utf-8&pn=頁碼

并且頁碼是0開始,50為一跳

是以這邊可以定義讀取的URL模闆是:"https://tieba.baidu.com/f?kw=" + 貼吧名字 + "&ie=utf-8&pn={}"

{}是代表占位符,後續讀取不同頁面的時候就占用該占位符位置

然後我們就可以進行爬取頁面資料的函數編寫了

此處這個函數,主要功能是用來擷取到貼吧清單頁面的資料# -*- coding:UTF-8 -*-

#設定間隔的

import time

#抓資料的

import requests

from bs4 import BeautifulSoup

#把資料弄能看的

import numpy as np

import pandas as pd

import docx

import xlrd

#上述是後面會用到的所有包,後續代碼中不再另外列出

tiebaname = str(input("請輸入貼吧名:")) #定義貼吧名字,使用者直接輸入

template_url = "https://tieba.baidu.com/f?kw=" + tiebaname + "&ie=utf-8&pn={}" #生成get請求的URL模闆

def search_n_pages(n):

#爬取n頁的資料,确認爬取頁數

target = []

#發起n次的get請求

for i in range(n):

#跟蹤進度

print('頁數:',i+1)

#按照浏覽貼吧的自然行為,每一頁50條

target_url = template_url.format(50*(i))

res = requests.get(target_url)

#轉為bs對象

soup = BeautifulSoup(res.text,'html.parser')

#擷取該頁文章清單

page_lst = soup.find_all(class_='j_thread_list clearfix')

#該頁資訊儲存到target裡

target.extend(extra_from_one_page(page_lst))

#休息2秒再通路

time.sleep(2)

return target

分析篩選關鍵詞及生成表單

然後有了貼吧頁面的資料以後,就需要對頁面資料進行篩選,篩選出需要的資料。

對應需求,篩選的關鍵詞應是:回複量

是以這邊,打開一個貼吧清單頁面,對着回複量進行右鍵--審查元素可以找到對應的

python爬貼吧回複_通過python爬取貼吧資料并儲存為word
python爬貼吧回複_通過python爬取貼吧資料并儲存為word

找到class值 這邊看到class值是 class="threadlist_rep_num center_text" 記錄下來備用,待會抓取資料的時候就要使用到這個

再然後,要抓取對應的标題和URL,右鍵文章标題,審查元素,就顯示出了具體的細節

python爬貼吧回複_通過python爬取貼吧資料并儲存為word

其中可以看到class值為class="j_th_tit ",而悄咪咪打開文章對比一下,你會發現,文章位址其實就是貼吧字首+href的值 如圖打開就是https://tieba.baidu.com/p/6297714220,其實就是https://tieba.baidu.com + a['href']

于是,回複量、标題、URL都擷取到了,接下來就是将他們的資料爬取下來儲存了

則這一段大概可以這麼寫:# 設定回複量門檻值 判斷輸入的回複量是否為int類型,不是的話重新要求輸入

while True:

try:

clicknum = int(input("請輸入要爬取的回複數(超過該回複數的才會被爬取):"))

break

except ValueError:

print("請輸入數字!")

M = clicknum

def extra_from_one_page(page_lst):

'''從一頁中提取 文章'''

# 臨時清單儲存字典資料,每一個文章都是一個字典資料

tmp = []

for i in page_lst:

#判斷是否超過門檻值(這邊的“threadlist_rep_num”實際上是頁面上顯示的回複量)

if int(i.find(class_='threadlist_rep_num center_text').text) > M:

dic = {}

#點選量

dic['num'] = int(i.find(class_='col2_left j_threadlist_li_left').text)

#文章名稱

dic['name'] = i.find(class_='j_th_tit').text

#文章位址

dic['address'] = 'https://tieba.baidu.com' + i.find(class_='j_th_tit').a['href']

tmp.append(dic)

return tmp

#爬取貼吧前n頁資料 如果輸入的不是int類型 則要求重新輸入

while True:

try:

num = int(input("請輸入要爬取的頁數:"))

break

except ValueError:

print("請輸入數字!")

d = search_n_pages(num)

# 轉化為pandas.DataFrame對象

data = pd.DataFrame(d)

# 導出到excel表格

xlsxname = tiebaname + '.xlsx'

data.to_excel(xlsxname)

這樣就是生成了表格檔案了

從表單中讀取URL并生成儲存為WORD文檔

接下來是要從表格中讀取URL,然後去列印到word裡并儲存檔案

首先先讀取上一步驟生成的表單'xlsxname',從中篩選出關鍵列'address',然後讀取整列,并儲存為清單(execl_list)#從生成的表格中讀取url清單,使url_write_word函數可以有讀取用的url_list

def execl_read_url(execl_list):

#打開指定表格

rbook = xlrd.open_workbook(execl_list)

rbook.sheets()

rsheet = rbook.sheet_by_index(0)

tmp = []

#周遊表格每一行

for row in rsheet.get_rows():

#保留指定的列數資料

product_column = row[3]

product_value = product_column.value

#去掉标題欄,将剩下的url儲存為一個清單

if product_value != 'address':

r = str(row[3])

r1 = r[6:-1]

tmp.append(r1)

return tmp

#讀取表格,生成url清單

execl_list = xlsxname

#将url清單儲存到url_list

url_list = execl_read_url(execl_list)

手中有一批的URL可以直接讀取了,那接着要怎麼去擷取他們的頁面裡的資料呢?

當然是通過通路他們來獲得資料。

打開随便一個文章,對着标題進行審查元素,如下圖

python爬貼吧回複_通過python爬取貼吧資料并儲存為word

可以看到

塊的class值是class="core_title_txt pull-left text-overflow " 留存備用,後續可以用作文檔标題和記錄

而抓取資料的話,就先抓取一樓就好,對着一樓進行審查元素,如下圖

python爬貼吧回複_通過python爬取貼吧資料并儲存為word

抓取到的class值是class="d_post_content j_d_post_content " 留存備用

接着有了這兩個值,就可以将網頁資料中想要的部分篩選出來并儲存了

調取之前生成的url清單,然後周遊清單的每個URL,逐一通路篩選出要儲存的資料,通過docx庫進行建立word文檔并寫入儲存,這部分就完成了#周遊url清單,通路并讀取資料儲存為word

def url_write_word(url_list):

tmp = '檔案生成完成'

s = 1

#周遊URL清單

for i in url_list:

tmp1 = []

print('生成檔案',s)

s += 1

i = str(i)

#讀取網頁

res = requests.get(i)

soup = BeautifulSoup(res.text,'html.parser')

url_title = soup.find(class_='core_title_txt pull-left text-overflow').text

t1 = url_title

t1 = t1[0:7] + '.docx'

#建立一個word文檔

doc = docx.Document()

url_word = soup.find(class_='d_post_content j_d_post_content').text

t2 = url_word

#将資料寫入word

doc.add_paragraph(i)

doc.add_paragraph(t2)

#儲存文檔

doc.save(t1)

return tmp

#生成word文檔

url_write_word(url_list)

小結

本文使用了如下幾個知識點:使用time子產品進行程式間隔循環

使用requests包進行get網頁資料

使用BeautifulSoup庫進行整理篩選網頁資料

使用pandas包進行整理資料

使用xlrd子產品進行讀取表格

使用docx包進行建立儲存文檔

參考資料