請參考源碼,文字是最先得想法,沒有再做更改。源碼以更新
前期準備:requests庫:使用pip install requests 安裝。
pymongo庫:使用pip install pymongo安裝。
首先分析目標url:http://roll.news.sina.com.cn/news/gnxw/gdxw1/index_1.shtml
這個url的規律很容易發現,我們通過更改index後面的數字便可以實現翻頁遍歷全部頁數。
接着我們審查網頁源代碼,我們找到html頁面中保存連接與新聞標題的部分,還有時間。
發現所有我們需要的信息都保存再li這個標籤下面,這裏我們可以用正則表達式來獲取所有我們需要的信息(標題,連接,日期)
pattern = re.compile(r'<li><.*?href="(.*?)".*?_blank">(.*?)</a><span>(.*?)</span>', re.S)
datas = re.findall(pattern, html)
然後是參與回覆與評論的:在獲取評論數量時會發現評論是用js的形式發送給瀏覽器的,所以要先把獲取的內容轉化爲json格式讀取python字典
url =http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-{需要添加}&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20
需要添加的部分爲標題url的
這樣我們可以寫出代碼:
def get_comm_par(href):
try:
id = re.search('doc-i(.+).shtml', href)
newsid = id.group(1)
commenturl = 'http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-{}&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20'
comment = requests.get(commenturl.format(newsid))
res = json.loads(comment.text.lstrip('var data='))
return res['result']['count']['total'], res['result']['count']['show']
except:
return None
這樣我們需要的標題,連接,時間,評論人數,參與人數都得到了。然後我們把這些信息寫入數據庫mongodb:
這部分可以寫成一個模塊在python中引入,還可以加別的參數,實現對網站更深度的遍歷。比如root_url。
MONGO_URL = 'localhost'
MONGODB = 'xinlang'
MONGOTABE = 'xinweng'
def write_to_mongodb(res, url):
if db[MONGOTABE].insert(res):
print('herf= {} save success'.format(url))
return True
print('save fail')
return False
全部寫完後,我們可以爲主函數設置多線程,這裏用的是python自帶的multiprocessing,使用方法也很簡單:
pool = multiprocessing.Pool()
pool.map(main, [x for x in range(1, 301)])
最後貼上全部代碼
希望對大家有參考作用:
import csv
import threading
import multiprocessing
import json
from urllib.parse import urlencode
from urllib.request import urlopen,Request,urlparse,build_opener,install_opener
from urllib.error import URLError,HTTPError
def html_download(url):
headers = {'User-Agent': "User-Agent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"}
request = Request(url, headers=headers)
try:
html = urlopen(request).read().decode()
except HTTPError as e:
html = None
print('[W] 下載出現服務器錯誤: %s' % e.reason)
return None
except URLError as e:
html = None
print("[E] 站點不可達: %s" % e.reason)
return None
return html
def api_info_manager(page):
#http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&show_all=1&show_num=6000&tag=1&format=json
comment_channel = [ 'gnxw', 'shxw','gjxw']
for comment in comment_channel:
data= {
'channel':'news',
'cat_1':comment,
'show_all':1,
'show_num':6000,
'tag':1,
'page':page,
'format':'json'
}
dataformat = 'http://api.roll.news.sina.com.cn/zt_list?'+urlencode(data)
response = html_download(dataformat)
#print(response)
json_results = json.loads(response,encoding='utf-8')['result']['data']
for info_dict in json_results:
yield info_dict
fileheader = ['id','column','title','url','keywords','comment_channel','img','level','createtime','old_level','media_type','media_name']
def write_csv_header(fileheader):
with open("新浪新聞.csv", "a",newline='') as csvfile:
writer = csv.DictWriter(csvfile, fileheader)
writer.writeheader()
def save_to_csv(result):
with open("新浪新聞.csv", "a",newline='') as csvfile:
print(' 正在寫入csv文件中.....')
writer = csv.DictWriter(csvfile, fieldnames=fileheader)
writer.writerow(result)
def main(page):
for res in api_info_manager(page):
save_to_csv(res)
if __name__ == '__main__':
#多線程
write_csv_header(fileheader)
pool = multiprocessing.Pool()
# 多進程
thread = threading.Thread(target=pool.map,args = (main,[x for x in range(1, 100)]))
thread.start()
thread.join()
喜歡爬蟲的可以加我Q(四七零五八一九八五)交流,我後面會更新自己在機器學習和大數據方面的探索。因爲還在實習,而且python學習時間不長,如有紕漏,希望大家點評。