之前的文章是爬蟲糗事百科并插入到MySQL數據庫,使用的是BeautifulSoup解析靜態網頁,select(返回列表)、find_all(返回列表)和find(返回單個結果)以及正則定位獲取網頁數據,pymysql鏈接插入本地MySQL數據庫。為了擴展自己的爬蟲技能,今天的代碼是爬蟲異步加載的簡書首頁文章,使用的是lxml解析網頁,XPath定位獲取網頁數據,以及pymongo鏈接插入本地Mongo數據庫(之前不懂MongoDB,看到很多人都使用Mongo數據庫存儲爬蟲數據,特別學習了一下,感覺這個非關系型數據庫還是很好用的)。爬取的首頁文章數據包括:標題,作者,發表時間,閱讀量,評論數,點贊數,打賞數,所投專題,代碼的完成參考了loading_miracle的文章,他的文章思路清晰,圖文并茂,很適合學習!下面是程序代碼,每一句都加了注釋說明,方便整理思路,代碼的寫法存在許多不規范的地方,還請大家留言指教,謝謝。
import requests
from lxml import etree
#import re
import pymongo
#構建爬取簡書首頁的類
class JianshuSpider(object):
#鏈接Mongo數據庫
client = pymongo.MongoClient('localhost', 27017)
#創建數據庫 mydb (應該叫連接數據庫,比較創建數據庫更合適)
mydb = client['mydb']
#創建數據表 jianshu
jianshu = mydb['jianshu']
#請求頭
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
}
#創建一個數組,用以存儲文章的id,作為異步加載的請求參數
params = []
#Class的構造函數(我習慣這么稱呼它)
def __init__(self):
pass
#獲取異步加載的url的函數(15頁),并請求數據
def totalpage(self):
for i in range(0,15):
data = '&'.join(self.params)
url = 'http://www.lxweimin.com/?' + data + '&page={}'.format(i)
self.get_data(url)
#爬取數據,并插入Mongo數據庫的函數
def get_data(self,url):
#模擬瀏覽器訪問網頁
html = requests.get(url,self.headers).text
#etree.HTML解析網頁內容返回給respone
response = etree.HTML(html)
#獲取請求文章的ID并存入數組并作為請求攜帶參數
ids = response.xpath('//*[@id="list-container"]/ul/li')
for one in ids:
one = 'seen_snote_ids[]=' + one.xpath('@data-note-id')[0]
self.params.append(one)
#xpath得到所有包含目標內容的div的集合
div_list = response.xpath('//*[@id="list-container"]/ul/li/div')
#for循環分別讀取d集合中的目標數據
for div in div_list:
#定位獲取文章標題數據-->text()
title = div.xpath('a/text()')[0]
#定位獲取作者名字數據-->text()
author = div.xpath('div[1]/div/a/text()')[0]
#定位獲取發表時間數據-->非文本text()而是屬性@
release_time = div.xpath('div[1]/div/span/@data-shared-at')[0]
#定位獲取文章閱讀量(用XPath無法定位獲取數據)
#reading_num = div.xpath('div[2]/a[2]/text()')[0]
#定位獲取文章評論數(用XPath無法定位獲取數據)
#comment_num = div.xpath('div[2]/a[3]/text()')
#定位獲取點贊數量
like_num = div.xpath('div[2]/span/text()')[0]
#打賞數和所投專題可能為None,顧需特別處理
#判斷所投專題
flg1 = div.xpath('div[2]/a[1]/text()')[0]
topic = div.xpath('div[2]/a[1]/text()')[0] if flg1!=None else ""
#判斷打賞數
flg2 = div.xpath('div[2]/span[2]/text()')
play_num = div.xpath('div[2]/span[2]/text()')[0] if len(flg2)>0 else 0
#爬取數據后,構建數據字典
data = {
'標題':title,
'作者':author,
'發布時間':release_time,
#'閱讀數':reading_num,
#'評論數':comment_num,
'點贊數':like_num,
'所投專題':topic,
'打賞數':play_num
}
#向數據庫插入數據
self.jianshu.insert_one(data)
if __name__ == '__main__':
#初始化簡書爬蟲這個類
jssy_spider = JianshuSpider()
#調用簡書爬蟲類的totalpage()函數
jssy_spider.totalpage()
插入MongDB效果:
簡書mongo.png
除文章的閱讀數和評論數沒有爬到,其他都插入到Mongo數據庫中了,很奇怪不知道為什么用XPath無法定位獲取這兩類數據,嘗試參照loading_miracle的文章改用正則表達式獲取,但是發現自己使用正則獲取數據后,分頁異步加載的數據不正確。第一次使用XPath,很多定位技巧都不掌握,還請大神幫忙解決用XPath定位這兩類數據。