爬蟲大作業


 

1.選一個自己感興趣的主題(所有人不能雷同)。

2.用python 編寫爬蟲程序,從網絡上爬取相關主題的數據。

3.對爬了的數據進行文本分析,生成詞雲。

4.對文本分析結果進行解釋說明。

5.寫一篇完整的博客,描述上述實現過程、遇到的問題及解決辦法、數據分析思想及結論。

6.最后提交爬取的全部數據、爬蟲及數據分析源代碼。

 

1.我選取的是糗事百科里面的 24小時專欄  網址是:https://www.qiushibaike.com/hot/,編譯語言是 python,工具是pycharm

2.爬取過程

  F12打開開發者工具 找到需要的內容

  

 可以清晰的看到信息都包含在<div class="content-block clearfix"></div> 中所以我們從其中找需要的內容

  這里我選取段子內容和up主截圖分別如下

這里可以清楚的知道 'up主'信息和'段子內容'都包含在<div id="content-left" class="col1"></div>中

  其中‘up主’信息包含在 <h2>標簽中,並且包含在<div class="article block untagged mb15 typs_long"></div>中,所以我們獲取 'up主'信息的代碼可以寫為:

1 up = soup.select('#content-left')[0].select('.article')[index].select('.author')[0].select('a')[1].text.strip('\n')

  而 '段子內容'包含在<div class="content"></div>的盒子中,並且包含在<div class="article block untagged mb15 typs_long"></div>中,所以我們獲取'段子內容'信息的代碼可以寫為:

content = soup.select('#content-left')[0].select('.article')[index].select('.content')[0].select('span')[0].text.strip('\n')

但是呢,有的用戶會以匿名方式發段子(大概害羞吧!!),會出現 一個錯誤:list out if range,那么該怎么辦呢?

答案在最后。

  獲取完單個需要的信息之后就是獲取整頁信息,想法是利用for循環獲取,因為上述內容都包含在<div class="article block untagged mb15 typs_long"></div>中,代碼如下:

  

1         for content_nums in range(sum_contents):
2             time.sleep(0.2)
3             duanzi_list.append(getContet(url, content_nums))

   獲取總的內容數目,思路是看HTML代碼,發現每個子項目都包含在<div id="content-left" class="col1"></div>中,所以可以得到其長度確定一頁的總子項目數目代碼如下:

1 def getAllContents(url):
2     # global onePage_AllContents
3     request = requests.get(url)
4     request.encoding = 'utf-8'
5     soup = BeautifulSoup(request.text,'html.parser')
6 
7     #一頁總內容數
8     onePage_AllContents = soup.select('#content-left')[0].select('.mb15').__len__()
9     return onePage_AllContents

  獲取完單頁,接下來就應該獲取所有頁面,

1 #獲取總頁數
2 def getAllPages(url):
3     request = requests.get(url)
4     request.encoding = 'utf-8'
5     soup = BeautifulSoup(request.text,'html.parser')
6 
7     number = int(soup.select('.page-numbers')[-1].text)
8     return number

  將上述綜合起來,寫到一個function中,獲取所有up主信息和段子內容:

 

def dict_Contents(url):
    request = requests.get(url)
    request.encoding = 'utf-8'
    soup = BeautifulSoup(request.text, 'html.parser')
    # time.sleep(1)
    duanzi_list = []
    sum_pages = getAllPages(url)  # 總頁數
    sum_contents = getAllContents(url)
    for page_nums in range(1, 4):
        url = 'http://www.qiushibaike.com/hot/page/{0}/'.format(page_nums)
        time.sleep(1)
        for content_nums in range(sum_contents):
            time.sleep(0.2)
            duanzi_list.append(getContet(url, content_nums))
    # for news in duanzi_list:
    #     print(news)
    return duanzi_list

由於我怕頁面未完全加載,可能會出現信息獲取錯誤,就添加一個time.sleep作為延遲,由於頁面較多,所以值選取了(1,4)的值。

 

   之后呢,應該生成Excel表,所以利用pandas第三方類庫生成Excel表

  import pandas
    df = pandas.DataFrame(list_Allduanzi)
    df.to_excel('duanzi.xlsx', engine='xlsxwriter')

  截圖:

  

  將要分詞的內容放進duanzi.txt中,代碼如下:

 

1 def writeNewsDetail(content):
2     f = open('duanzi.txt', 'a', encoding='utf-8')
3     f.write(content)
4     f.close()

 

  截圖如下:

  有了內容之后,接下來就是分詞,我分詞的類庫選擇的是jieba分詞,是一個比較好的分詞,在pycharm中可以直接搜索添加,也可以在命令行中添加 指令是'pip install jieba',但是在命令行中添加需先配置環境變量。那么分詞的話,首先,要去掉標點符號。將內容中的標點符號等分隔符全部替換為空格。接着,進行分詞切割,(同時我們可以去掉我們不需要的信息放在一個集合里)進行詞頻統計。並保存在文件中,代碼如下:

  

 1  import jieba
 2     file = open('duanzi.txt', 'r', encoding='utf-8')
 3     duanzi = file.read()
 4     file.close()
 5 
 6     sep = '''-/.。""'',!?;:~`·[] \ ,:;“”?!-、}{【】‘’'''
 7     exclude = {' ','\ue412','\x01','','','','','','我們','','……',''}
 8 
 9     for char in sep:
10         duanzi = duanzi.replace(char,'')
11     duanziList = list(jieba.cut(duanzi))#分詞
12     duanziDict = {}
13     duanzis = list(set(duanziList)-exclude)#刪除非中國漢語字符
14 
15     for d in range(0,len(duanzis)):
16         duanziDict[duanzis[d]] = duanzi.count(str(duanzis[d]))
17 
18     dictList = list(duanziDict.items())
19     dictList.sort(key=lambda x:x[1],reverse=True)
20 
21     f = open('count.txt','a',encoding='utf-8')
22     for i in range(150):
23         print(dictList[i])
24         f.write(dictList[i][0] + ':' + str(dictList[i][1]) + '\n')
25     f.close()

  截圖結果如下:

  最后一步就是生成詞雲了。首先是下載,但是呢在pycharm和命令行下載是行不通的需要通過下載被的文件在使用命令行才行,問題解決有提及。那么代碼是:

 

 1     #生成詞雲
 2     from PIL import Image, ImageSequence
 3     import numpy as np
 4     import matplotlib.pyplot as plt
 5     from wordcloud import WordCloud, ImageColorGenerator
 6 
 7     font = r'C:\Windows\Fonts\simhei.TTF'
 8     image = Image.open('./qiushibaike.jpg')
 9     graph = np.array(image)
10     wc = WordCloud(font_path=font, background_color='White', max_words=50, mask=graph)
11     wc.generate_from_frequencies(duanziciyun)
12     image_color = ImageColorGenerator(graph)
13     plt.imshow(wc)
14     plt.axis("off")
15     plt.show()

 

  詞雲圖片形狀是(根據那個糗事百科的背景圖):

  生成的詞雲截圖如下:

 

  總的代碼如下:

 

  1 # -*- coding: UTF-8 -*-
  2 import requests
  3 import re
  4 from bs4 import BeautifulSoup
  5 import time
  6 import openpyxl
  7 import xlsxwriter
  8 
  9 #保存到文本
 10 def writeNewsDetail(content):
 11     f = open('duanzi.txt', 'a', encoding='utf-8')
 12     f.write(content)
 13     f.close()
 14 
 15 #獲取
 16 def getContet(url,index):
 17     global up, content
 18     request = requests.get(url)
 19     request.encoding = 'utf-8'
 20     soup = BeautifulSoup(request.text,'html.parser')
 21 
 22     duanzi = {}  # 用字典存放信息
 23 
 24     #up主
 25     try:
 26         up = soup.select('#content-left')[0].select('.article')[index].select('.author')[0].select('a')[1].text.strip('\n')
 27         #內容
 28         content = soup.select('#content-left')[0].select('.article')[index].select('.content')[0].select('span')[0].text.strip('\n')
 29     except IndexError:
 30         up = soup.select('#content-left')[0].select('.article')[index].select('.author')[0].select('h2')[0].text.strip('\n')
 31         content = soup.select('#content-left')[0].select('.article')[index].select('.content')[0].select('span')[0].text.strip('\n')
 32     duanzi['up主'] = up
 33     duanzi['段子內容'] = content
 34     writeNewsDetail(content)
 35     return duanzi
 36 
 37 #獲取總頁數
 38 def getAllPages(url):
 39     request = requests.get(url)
 40     request.encoding = 'utf-8'
 41     soup = BeautifulSoup(request.text,'html.parser')
 42 
 43     number = int(soup.select('.page-numbers')[-1].text)
 44     return number
 45 
 46 #獲取總的段子數目
 47 def getAllContents(url):
 48     # global onePage_AllContents
 49     request = requests.get(url)
 50     request.encoding = 'utf-8'
 51     soup = BeautifulSoup(request.text,'html.parser')
 52 
 53     #一頁總內容數
 54     onePage_AllContents = soup.select('#content-left')[0].select('.mb15').__len__()
 55     return onePage_AllContents
 56 
 57 # 將所有段子存放到字典中
 58 def dict_Contents(url):
 59     request = requests.get(url)
 60     request.encoding = 'utf-8'
 61     soup = BeautifulSoup(request.text, 'html.parser')
 62     # time.sleep(1)
 63     duanzi_list = []
 64     sum_pages = getAllPages(url)  # 總頁數
 65     sum_contents = getAllContents(url)
 66     for page_nums in range(1, 4):
 67         url = 'http://www.qiushibaike.com/hot/page/{0}/'.format(page_nums)
 68         time.sleep(1)
 69         for content_nums in range(sum_contents):
 70             time.sleep(0.2)
 71             duanzi_list.append(getContet(url, content_nums))
 72     # for news in duanzi_list:
 73     #     print(news)
 74     return duanzi_list
 75 
 76 
 77 if __name__ == '__main__':
 78     url = 'http://www.qiushibaike.com/hot/'
 79     # request = requests.get(url)
 80     # request.encoding = 'utf-8'
 81     # soup = BeautifulSoup(request.text, 'html.parser')
 82     list_Allduanzi = []
 83     list_Allduanzi = dict_Contents(url)
 84     #生成excel表
 85     import pandas
 86     df = pandas.DataFrame(list_Allduanzi)
 87     df.to_excel('duanzi.xlsx', engine='xlsxwriter')
 88 
 89     import jieba
 90     file = open('duanzi.txt', 'r', encoding='utf-8')
 91     duanzi = file.read()
 92     file.close()
 93 
 94     sep = '''-/.。""'',!?;:~`·[] \ ,:;“”?!-、}{【】‘’'''
 95     exclude = {' ','\ue412','\x01','','','','','','我們','','……',''}
 96 
 97     for char in sep:
 98         duanzi = duanzi.replace(char,'')
 99     duanziList = list(jieba.cut(duanzi))#分詞
100     duanziDict = {}
101     duanzis = list(set(duanziList)-exclude)#刪除非中國漢語字符
102 
103     for d in range(0,len(duanzis)):
104         duanziDict[duanzis[d]] = duanzi.count(str(duanzis[d]))
105 
106     dictList = list(duanziDict.items())
107     dictList.sort(key=lambda x:x[1],reverse=True)
108     duanziciyun = {}
109     f = open('count.txt','a',encoding='utf-8')
110     for i in range(150):
111         f.write(dictList[i][0] + ':' + str(dictList[i][1]) + '\n')
112         duanziciyun[dictList[i][0]] = dictList[i][1]
113     f.close()
114 
115     #生成詞雲
116     from PIL import Image, ImageSequence
117     import numpy as np
118     import matplotlib.pyplot as plt
119     from wordcloud import WordCloud, ImageColorGenerator
120 
121     font = r'C:\Windows\Fonts\simhei.TTF'
122     image = Image.open('./qiushibaike.jpg')
123     graph = np.array(image)
124     wc = WordCloud(font_path=font, background_color='White', max_words=50, mask=graph)
125     wc.generate_from_frequencies(duanziciyun)
126     image_color = ImageColorGenerator(graph)
127     plt.imshow(wc)
128     plt.axis("off")
129     plt.show()

 

 

 

3.遇到的問題以及解決辦法 

   第一個問題是:上述一開始提及到的,有些up主並非公開的,是匿名用戶,它的結構和非匿名用戶不一樣,那么,我就點擊查看,發現只有<span>標簽並沒<h2>標簽,所以我的代碼修改如下:

1 #up主
2     try:
3         up = soup.select('#content-left')[0].select('.article')[index].select('.author')[0].select('a')[1].text.strip('\n')
4         #內容
5         content = soup.select('#content-left')[0].select('.article')[index].select('.content')[0].select('span')[0].text.strip('\n')
6     except IndexError:
7         up = soup.select('#content-left')[0].select('.article')[index].select('.author')[0].select('h2')[0].text.strip('\n')
8         content = soup.select('#content-left')[0].select('.article')[index].select('.content')[0].select('span')[0].text.strip('\n')  

  問題就解決了,其中還學習到了,當 出現錯誤 'list out of range'時,可以運用try except IndexEorro 處理和尋找問題的根源。

  第二個問題是:在利用pandas庫生成excel表時,產生了錯誤 'openpyxl.utils.exceptions.IllegalCharacterError',我解決的辦法是在google搜索該問題,然后在stackflow中找到了答案,下載並且導入 ‘import xlsxwriter’ 然后修改導入數據到excel的代碼 ‘df.to_excel('duanzi.xlsx', engine='xlsxwriter')’就OK了。

  第三個問題是:詞雲wordcloud載pycharm下載不成功,原因是找不到該文件的詳情信息,估計是該工具引進python第三方類庫有問題,利用pip進行安裝也不成功,那么問題就漸漸浮出水面了,就是匹配不到該文件的版本號,所以,我們需要知道該版本號,上網查了下,因為我的python是3.6版本,所以對應cp36,然后我的是windows系統,所以在LDF中下windows版本的,鏈接是:https://www.lfd.uci.edu/~gohlke/pythonlibs/#wordcloud,下載amd的,拖入你的python路徑中,具體文件目錄就自行百度吧(我忘記了!!!)。

我是用anacanda 進行引進該第三方類庫的,參考鏈接:https://www.jianshu.com/p/e4b24a734ccc。

  問題大概就這么多了。

 

 4.數據分析思想以及結論

獲取段子內容並且進行詞頻統計,就可以了解現在的人說的是什么梗,或者有什么關鍵詞特別突出即,當你講笑話或者處於尷尬情況是可以將一兩個笑話和諧一下氣氛,也可以用這寫梗去交朋友或者哄別人開行,(哄女孩子什么的我沒說。。哈),總之是很有用的,但是呢,我不曉得為什么生成的都是一個一個詞的,並沒有很多詞組,不知道是不是結巴分詞的一個缺點。

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM