1. 程式人生 > >python3 requests簡單爬蟲以及分詞並製作詞雲

python3 requests簡單爬蟲以及分詞並製作詞雲

現在學的東西很雜,很多時候要學的東西其實以前都寫過,但是都忘了。現在回想起來,很多以前寫的程式碼基本上就都沒有儲存下來,感覺有些可以。一方面不便於以後的查詢和複習,另一方面也丟失了很多記錄。所以打算以後的程式碼片段都盡力儲存下來,並寫在部落格裡。

這個是好幾天前無聊寫的,因為不想寫演算法。。就是爬去了知乎https://www.zhihu.com/question/27964933這個問題下面的所有答案,然後做了個分詞,按照頻率再做個詞雲。至於問什麼是這個問題。。原諒我單身20年的怨念。。

得出來的詞雲是這個樣子的:
詞雲

雖然和預想中不太一樣,沒有什麼特別顯著的結果,但還是很炫酷啊

程式碼分兩部分,第一部分,爬取知乎這個問題下面的所有答案,爬知乎還是挺方便的,api基本都是json格式的。
程式碼如下:

import requests
import pymysql
from time import sleep
from random import gauss
conn = pymysql.connect(host,username,password,databaseName,use_unicode=True,charset='utf8')
sess = requests.Session()
mycookies = {}
myheaders = {}
with open('zhihu.conf','rb') as f:
    lines = f.readlines()
    for line
in lines: line = line.decode('utf-8') print(line) k,v = line.split(':',1) k = k.strip() v = v.strip() if k.lower()!='cookie': pass else: cookies = v.split(';') for cookie in cookies: k,v = cookie.split
('=',1) k = k.strip() v = v.strip() mycookies[k] = v requests.utils.add_dict_to_cookiejar(sess.cookies,mycookies) myheaders = {\ 'Host': 'www.zhihu.com',\ 'Referer': 'https://www.zhihu.com/',\ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0'} step = 20 offset = 3677 cur = conn.cursor() while True: r = sess.get("https://www.zhihu.com/api/v4/questions/27964933/answers?include=data[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,upvoted_followees;data[*].mark_infos[*].url;data[*].author.follower_count,badge[?(type=best_answerer)].topics&offset=%d&limit=20&sort_by=default" % offset,headers = myheaders) dataset = r.json().get('data') pointer = 0 for data in dataset: name = data.get('author').get('name') url_token = data.get('author').get('url_token') voteup_count = data.get('voteup_count') comment_count = data.get('comment_count') content = data.get('content') print('offset',offset+pointer+1) print('name',name) print('url_token',url_token) print('voteup_count',voteup_count) print('comment_count',comment_count) print('content',content) print('--------------------------') pointer += 1 query = "insert into ex2 (name,url_token,voteup_count,comment_count,content) values (%r,%r,%r,%r,%r)" % (name,url_token,voteup_count,comment_count,content) try: cur.execute(query) conn.commit() except Exception as e: print(e) conn.rollback() conn.close() raise e if len(dataset)!=step: print('length is not equal to the step : len(dataset) = '+str(len(dataset))) break offset += step sleep(5+gauss(3,1))

程式碼不是很精煉,因為是邊除錯邊改的,調通了以後也沒優化了(懶。。)
解釋下程式碼,裡面讀取了一個叫zhihu.conf的檔案,這個檔案裡面是這個樣子滴:

這裡寫圖片描述
為什麼要這樣子呢,因為這段文字是從firefox裡面的f12開發者模式裡面直接拷貝下來的,我懶得手動新增cookie了,所以簡單寫了段程式來解析cookie並新增進session
雖然程式不難,但還是有幾個坑,記錄下來備忘:

  1. pymysql連線的時候要加use_unicode=True,charset=’utf8’,否則會編碼錯誤
  2. 請求頭要注意,我原來用的是zhihu.conf裡面的那種原封不動給了headers,結果不行。後來發現請求頭不能太多,只要有host,referer,ua就行了。到底是為什麼我不確定,沒深究了,懷疑可能是Connection: keep-alive的問題
  3. 那個sleep的時間我用了個gauss就是弄著玩的,沒測試是不是必要的
  4. 中間斷了一次,手動給接上了,原因。。不知道,沒去研究了

    總之就這樣拍下來大概6000多個答案,嗯看了一樣資料庫,是6011個答案。接下來就是第二部分,從資料庫把所有的答案弄下來然後分詞,並製作詞雲。這裡邊用到了三個模組。beautifulsoup用來解析知乎的答案內容(因為裡面有很多html標籤),jieba用來分詞,wordcloud用來製作詞雲,程式碼如下:

其中用到了一個ex2.json,這個檔案是我從phpmyadmin裡面直接down下來的,格式長下面這樣:
這裡寫圖片描述
因為基本上每個答案後面都被知乎自動加了一句著作權歸作者所有,禁止轉載,所以把這句話去掉,防止影響後面的頻率統計
注意點:

  • wordCloud預設不支援中文的,要想支援的話一定要加上font_path引數,指定一箇中文字型才行。否則會把中文顯示成框框
  • 我用了jieba.posseg.cut而不是直接jieba.cut,這樣可以詞性標註,從而排除一些不想要的詞。我第一次沒用詞性標註,結果出來了很多代詞,比如“我們”。。所以我排除了代詞

189萬多字,最後綜合成了這樣一張圖。我不禁感嘆:怪不得我找不到妹子 ╮(๑•́ ₃•̀๑)╭