在爬取某站時並做簡單分析時,遇到如下問題和大家分享,避免犯錯:
一丶網站的path為 /info/1013/13930.htm ,其中13930為不同新聞的 ID 值,但是這個數雖然為升序,但是沒有任何規律的升序。
解決辦法:
使用 range 順序爬取,錯誤的網站在頁面會報如圖錯誤:
這時我們首先去判斷返回頁面是否包含 str 'Sorry, Page Not Found',如果包含則跳過,不包含則爬取頁面關鍵信息
二、在爬取過程中發現有其它頁面,該內容已經被撤銷,這時我正常去判斷頁面,並跳過,發現無法跳過
解決辦法:
查看頁面編碼為:UTF-8
在用 if 判斷頁面是否存在 str 時,首先將頁面內容進行UTF-8編碼即可解決:
response.encoding = 'utf-8'
三、在爬取網站時,遇到了沒有 text 的主頁面,新聞全部為圖片
解決辦法:這時查看圖片頁面和新聞頁面的不同
圖片頁面關鍵標簽:
新聞頁面關鍵標簽:
發現div標簽下的 ID 不同,這時我們就跳過 id = 'vsb_content' 即可,在跳過時,判斷頁面內容應當先判斷 id = 'vsb_content_4' ,因為 vsb_content_4 包含了 vsb_content
四、在爬取新聞后,將新聞寫入csv文件時出現BUG,文件內容有重復
解決辦法:
在寫入文件的列表寫入后將列表清空,因為在循環執行跳過不存在頁面時會有空隙,這時的data_list里面是有內容的
五、在寫入csv文件后,新聞文本亂碼
解決辦法:使用utf-8-sig編碼
為什么不用utf-8?
原因如下:
1、”utf-8“ 是以字節為編碼單元,它的字節順序在所有系統中都是一樣的,沒有字節序問題,
因此它不需要BOM,所以當用"utf-8"編碼方式讀取帶有BOM的文件時,它會把BOM當做是文件內容來處理, 也就會發生類似上邊的錯誤.
2、“uft-8-sig"中sig全拼為 signature 也就是"帶有簽名的utf-8”,
因此"utf-8-sig"讀取帶有BOM的"utf-8文件時"會把BOM單獨處理,與文本內容隔離開,也是我們期望的結果.
最終代碼:

1 #!/user/bin/env python 2 # -*- coding:utf-8 -*- 3 # Author: Mr.riy 4 5 6 import re 7 import requests 8 import csv 9 import time 10 import jieba 11 import jieba.analyse 12 from requests.exceptions import RequestException 13 from bs4 import BeautifulSoup 14 15 16 class Downloader: 17 def __init__(self): 18 self.data_list = [] 19 20 def download(self, url, num_retries=3): 21 '判斷頁面' 22 print('Downloading:', url) 23 global response 24 response = requests.get(url) 25 response.encoding='utf-8' 26 try: 27 if 'Sorry, Page Not Found' in response.text: 28 print(url, '頁面不存在') 29 elif '該內容已經被撤銷' in response.text: 30 print(url, '頁面不存在') 31 elif response.status_code == 200: 32 print('下載成功,開始執行......') 33 # print(response.text) 34 # print(response.encoding) 35 page = response.content 36 self.find_all(page) 37 time.sleep(1) 38 else: 39 if num_retries > 0 and 500 <= response.status_code <= 600: 40 html = self.download(url, num_retries-1) 41 except RequestException as e: 42 print(e) 43 44 def find_all(self, page): 45 '爬取內容' 46 soup_title = BeautifulSoup(page, 'lxml') 47 sp_title_items = soup_title.find('h2', attrs={'align': 'center'}) 48 title = sp_title_items.text 49 print(title) 50 51 sp_time_items = soup_title.find('div', attrs={'style': 'line-height:400%;color:#444444;font-size:14px'}) 52 times = sp_time_items.text 53 # print(times) 54 time = re.findall(r'\d{4}年\d{2}月\d{2}日 \d{2}:\d{2}', times) 55 # print(time) 56 author = re.findall(r'作者:(.*)', times) 57 # print(author) 58 global response 59 if 'vsb_content_4' in response.text: 60 sp_words_items = soup_title.find('div', attrs={'id': 'vsb_content_4'}) 61 elif 'vsb_content_501' in response.text: 62 sp_words_items = soup_title.find('div', attrs={'id': 'vsb_content_501'}) 63 else: 64 sp_words_items = soup_title.find('div', attrs={'id': 'vsb_content'}) 65 66 words = sp_words_items.text 67 # print(words) 68 row = [] 69 row.append(time) 70 row.append(author) 71 row.append(words) 72 self.data_list.append(row) 73 74 def write_csv(self, filename, all_list): 75 '寫入csv文件' 76 with open(filename, 'w', encoding="utf-8-sig", newline='') as f: 77 writer = csv.writer(f) 78 fields = ('時間', '作者', '內容') 79 writer.writerow(fields) 80 for row in all_list: 81 writer.writerow(row) 82 83 def fetch_data(self): 84 '設置爬取頁面' 85 all_list = [] 86 for page in range(13795, 14000, 1): #設置爬取的頁面范圍 87 url = f'http://www.xxxxxx.cn/info/1013/{page}.htm' 88 self.download(url) 89 all_list += self.data_list 90 self.data_list = [] 91 92 self.write_csv('data.csv', all_list) 93 94 95 class analyze: 96 def get_all_text(self, filename): 97 '取出所有評價的句子' 98 comment_list = [] 99 with open(filename, encoding="utf-8-sig") as f: 100 rows = csv.reader(f) 101 for row in rows: 102 one_comment = row[-1] 103 comment_list.append(one_comment) 104 105 return ''.join(comment_list[1:]) 106 107 def cut_text(self, all_text): 108 '找到評價中重要關鍵詞' 109 jieba.analyse.set_stop_words('stop_words.txt') 110 text_tags = jieba.analyse.extract_tags(all_text, topK=30) 111 return text_tags 112 113 114 def main(): 115 temp = Downloader() 116 temp.fetch_data() 117 b = analyze() 118 all_text = b.get_all_text('data.csv') 119 text_tags = b.cut_text(all_text) 120 print(text_tags) 121 122 123 if __name__ == "__main__": 124 main()
運行截圖:最近新聞出現最多的關鍵字為:防疫,疫情,工作