🍬 博主介紹
- 👨?🎓 博主介紹:大家好,我是可可卷,很高興和大家見面~
- ?主攻領域:【資料分析】【機器學習】 【深度學習】 【資料可視化】
- 🎉歡迎關注💗點贊👍收藏??評論📝
- 🙏作者水平很有限,歡迎各位大佬指點,一起學習進步!

📚文章目錄
🍬 博主介紹
🍭0 教程說明
🍭1 分析url
🍭2 關閉登錄彈窗
🍭3 獲取所有答案
🍭4 獲取標題和副標題
🍭5 展開評論
🍭6 按塊獲取答案
🍭7 保存資訊
🍥7.1 json
🍥7.2 csv
🍥7.3 txt
🍥7.4 資料庫
🍭8 結語
🍭0 教程說明
使用selenium可以直接獲得加載后的網頁資訊而無需考慮請求資訊,Ajax,js解密等等,可謂偷懶神器,下面以 你讀懂帶土了嗎? - 知乎
https://www.zhihu.com/question/375762710 為例,進行實戰講解
特殊宣告:本教程僅供學習,若被他人用于其他用途,與本人無關
🥚🥚🥚我是分割線🥚🥚🥚
🍭1 分析url
分析網址,可以發現網址是https://www.zhihu.com/question/ + question_id,因此可以通過下述代碼構建url:
try: option = webdriver.ChromeOptions() option.add_argument("headless") option.add_experimental_option("detach", True) driver = webdriver.Chrome(chrome_options=option) driver.get('https://www.zhihu.com/question/'+question_id) except Exception as e: print(e) finally: driver.close()
🥚🥚🥚我是分割線🥚🥚🥚
🍭2 關閉登錄彈窗
進入網頁,由于未登錄,因此會出現登錄彈窗,我們可以通過Xpath和CSS選擇器的方式獲取關閉按鈕,模擬點擊操作
# 先觸發登陸彈窗, WebDriverWait(driver, 40, 1).until(EC.presence_of_all_elements_located( (By.CLASS_NAME, 'Modal-backdrop')), waitFun()) # 關閉登陸視窗 driver.find_element_by_xpath('//button[@class="Button Modal-closeButton Button--plain"]').click()
🥚🥚🥚我是分割線🥚🥚🥚
🍭3 獲取所有答案
由于知乎是動態加載,需要將滾輪滑動到底部才能獲得全部答案,因此需要運行js獲得頁面高度,并模擬滾輪下滑
def waitFun(): js = """ let equalNum = 0; window.checkBottom = false; window.height = 0; window.intervalId = setInterval(()=>{ let currentHeight = document.body.scrollHeight; if(currentHeight === window.height){ equalNum++; if(equalNum === 2){ clearInterval(window.intervalId); window.checkBottom = true; } }else{ window.height = currentHeight; window.scrollTo(0,window.height); window.scrollTo(0,window.height-1000); } },1500)""" driver.execute_script(js) def getHeight(nice): js = """ return window.checkBottom; """ return driver.execute_script(js) # 當滾動到底部時 WebDriverWait(driver, 40, 3).until(getHeight, waitFun()) # 等待加載 sleep(1)
🥚🥚🥚我是分割線🥚🥚🥚
🍭4 獲取標題和副標題
需要注意,有些問題是沒有副標題的,因此也不存在副標題的element
title=driver.find_element_by_xpath('//h1[@class="QuestionHeader-title"]').text subtitle = driver.find_element_by_xpath('//span[@class="RichText ztext css-hnrfcf"]').text
🥚🥚🥚我是分割線🥚🥚🥚
🍭5 展開評論
由于評論的資料并不包含在頁面中,而需要點擊 “XX條評論” 按鈕后才進行動態加載,因此需要模擬點擊這些按鈕
![]()
wait=WebDriverWait(driver,30) #顯式等待 path=(By.XPATH,'//button[@class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"]') clicks=wait.until(EC.presence_of_all_elements_located(path)) for c in clicks: if '條' in c.text: driver.execute_script("arguments[0].click();", c) sleep(0.1)
🥚🥚🥚我是分割線🥚🥚🥚
🍭6 按塊獲取答案
先分析得到每一個問題的答主資訊、回答內容、評論都在 “List-item”下
然后在每一塊元素的基礎上,在進行答主資訊、回答內容、評論的查找
# get blocks blocks=driver.find_elements_by_xpath('//div[@class="List-item"]') res=[] for b in blocks: author = b.find_element_by_xpath('.//div[@class="ContentItem-meta"]//meta[@itemprop="name"]').get_attribute('content') content = b.find_element_by_xpath('.//div[@class="RichContent-inner"]').text # button=b.find_element_by_xpath('.//div[@class="ContentItem-actions"]//button[contains(text(),"評論")]') button=b.find_element_by_xpath('.//button[@class="Button ContentItem-action Button--plain Button--withIcon Button--withLabel"]') if '收起' in button.text: comment = b.find_elements_by_xpath('.//ul[@class="NestComment"]') comments='' for c in comment: comments+=c.text print(comments) sleep(0.2) else: comments = '無評論' tmp={'author':author,'content':content,'comments':comments} res.append(tmp)
🥚🥚🥚我是分割線🥚🥚🥚
🍭7 保存資訊
🍥7.1 json
json_str = json.dumps(res) with open(filename+'.json', 'w',encoding='utf-8') as json_file: json_file.write(json_str)
🍥7.2 csv
df = pd.DataFrame(res) df.to_csv(filename+'.csv')
🍥7.3 txt
cwd=os.getcwd() with open(cwd++filename+'.txt','a',encoding='utf-8')as f: for i,r in enumerate(res): f.write(f'第{i+1}個回答'.center(30,'=')) f.write('\n') f.write(f'author:{r["author"]}\n') f.write(f'content:{r["content"]}\n') f.write(f'comments:\n{r["comments"]}\n')
🍥7.4 資料庫
通過pymysql或pymongo保存到資料庫中,有興趣的可以再去了解
🥚🥚🥚我是分割線🥚🥚🥚
🍭8 結語
不知道大家在爬取之前,是否注意到知乎遵循了robots協議(沒有關注過的可以點擊這個網址:https://www.zhihu.com/robots.txt)
為了不給網站的管理員帶來麻煩,希望大家在爬取的時候能盡量遵循robots協議;若在學習程序中在不可避免地無法遵循robots協議,也盡量維持爬蟲爬取頻率與人類正常訪問頻率相當,不過多占用服務器資源,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/390365.html
標籤:python



