完整代碼可以關(guān)注公眾號:Romi的雜貨鋪
首先打開京東的任意幾個商品頁面,并觀察URL,可以發(fā)現(xiàn)都是https://item.jd.com/+數(shù)字+.htm的格式,而且數(shù)字也隨著商品的改變而改變,基本上可以確定這串數(shù)字是商品ID
之后我們找到網(wǎng)頁的源碼并隨便復(fù)制一句評論,在網(wǎng)頁源碼中查找,發(fā)現(xiàn)并沒有找到評論內(nèi)容,說明jd的評論頁面并非靜態(tài)網(wǎng)頁
AJAX:
AJAX的全稱是Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。
ajax不是新的編程語言,而是一種使用現(xiàn)有標準的新方法。ajax是與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁的藝術(shù),在不重新加載整個頁面的情況下。
ajax是一種在無需重新加載整個網(wǎng)頁的情況下,能夠更新部分網(wǎng)頁的技術(shù)。
ajax是一種用于創(chuàng)建快速動態(tài)網(wǎng)頁的技術(shù)。通過在后臺與服務(wù)器進行少量數(shù)據(jù)交換。ajax可以使網(wǎng)頁實現(xiàn)異步更新。這意味著可以在不重新加載整個網(wǎng)頁的情況下,對網(wǎng)頁的某部分進行更新。而傳統(tǒng)的網(wǎng)頁(不使用ajax)如果需要更新內(nèi)容,必須重載整個網(wǎng)頁面。
既然確定是AJAX的方式加載,我們可以直接打開chrome的調(diào)試工具,在network中的XHR和JS中尋找保存有評論的文件。注意這里必須先下拉到評論頁面使數(shù)據(jù)文件加載下來,否則會找不到加載的數(shù)據(jù)文件
我們可以通過兩種方式來查找包含評論的文件:
1.可以在js和XHR中尋找comment關(guān)鍵字,查看是否有文件符合要求,并對符合要求的結(jié)果篩選
2.評論在頁面的最下方,根據(jù)文件的加載順序可以大致了解到會在后面,從后面開始找即可
最終確定js文件,如下圖所示
這樣我們就可以確定評論的請求地址并開始抓取
import requestsimport jsonurl='https://item.jd.com/52297931949.html'jsonurl='https://club.jd.com/comment/productPageComments.action?productId=52297931949&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1'html=requests.get(jsonurl).text#print(html)josntext=json.loads(html)comments= josntext['comments']for comment in comments: content = comment['content'] print(content)
這里需要注意一下原始的jsonurl得到的文件并不是標準的json文件格式,我們可以將得到的文本內(nèi)容復(fù)制到https://www.json.cn發(fā)現(xiàn)這并不是一個標準的josn文件,所以直接loads()會直接報錯:json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0),只要返
回的對象不是josn對象就會出現(xiàn)此錯誤
解決的方法有兩個,一是將URL中的?callback=fetchJSON_comment98去除,另外一種方法是將返回的文本對象中的fetchJSON_comment98替換為空
得到所需要的json文件后就可以將數(shù)據(jù)存到sqllite中了
sqllite是python內(nèi)置的關(guān)系型數(shù)據(jù)庫,具有以下優(yōu)點:
不需要一個單獨的服務(wù)器進程或操作的系統(tǒng)(無服務(wù)器的)。
SQLite不需要配置,這意味著不需要安裝或管理。
一個完整的SQLite數(shù)據(jù)庫是存儲在一個單一的跨平臺的磁盤文件。
SQLite是非常小的,是輕量級的,完全配置時小于 400KiB,省略可選功能配置時小于250KiB。
SQLite是自給自足的,這意味著不需要任何外部的依賴。
SQLite事務(wù)是完全兼容 ACID 的,允許從多個進程或線程安全訪問。
SQLite支持 SQL92(SQL2)標準的大多數(shù)查詢語言的功能。
SQLite使用 ANSI-C 編寫的,并提供了簡單和易于使用的 API。
SQLite 在 UNIX(Linux, Mac OS-X, Android,iOS)和 Windows(Win32, WinCE,WinRT)中運行。
python操作SQLite流程與連接其他的數(shù)據(jù)庫相同,大概分為以下五步
通過sqlite3.open()創(chuàng)建與數(shù)據(jù)庫文件的連接對象connection;
通過connection.cursor()創(chuàng)建光標對象cursor;
通過cursor.execute()執(zhí)行SQL語句;
通過connection.commit()提交當前的事務(wù),或者通過cursor.fetchall()獲得查詢結(jié)果;
通過connection.close()關(guān)閉與數(shù)據(jù)庫文件的連接
這一部分代碼如下所示
conn=sqlite3.connect("comments.db")#建立連接,數(shù)據(jù)庫存在時,直接連接;不存在時,創(chuàng)建相應(yīng)數(shù)據(jù)庫#新建一張表conn.execute('''CREATE TABLE Comments_jd (ID text PRIMARY KEY NOT NULL, comment text );''')#注意sql語句中使用了格式化輸出的占位符%s和%d來表示將要插入的變量,其中%s需要加引號''for comment in comments: sql = "insert into Comments_jd(ID,comment) values('%s','%s')" % (comment['id'],comment['content']) conn.execute(sql)conn.commit()# 關(guān)閉數(shù)據(jù)庫連接conn.close()
之后檢查以下數(shù)據(jù)是否有問題:
conn=sqlite3.connect("comments.db")cursor = conn.execute("select * from Comments_jd")for row in cursor: print('ID = ', row[0], ' Comment = ', row[1])conn.close()
得到的結(jié)果如下圖所示
這樣整個流程就搞定了