mit=item.find('div',class_='p-mit').strong.get_text(strip=true)ifitem.find('div',class_='p-mit')else'0'
books.append([title,price,shop,mit])
exceptattributeerrorase
print(f"解析錯誤{e},跳過此項")
continue
df=pd.dataframe(books,columns=['書名','價格','店鋪','評價數'])
df.to_csv('jd_math_books_page1.csv',index=false,encoding='utf-8-sig')
短短幾十行代碼,他調試了大半天。問題層出不窮:標簽class名不準確、某些商品信息缺失導致find返回none進而引發attributeerror、價格符號和評價文本中夾雜著“¥”、“+”等需要清洗的字符、以及最棘手的――京東的部分商品信息是通過javascript動態加載的,直接請求html頁面獲取不到。他不得不學習使用requests抓取實際的接口數據(通過開發者工具查看work中的xhr請求),這比解析靜態html復雜得多。
第四、五天:優化、多頁抓取與當當網適配。
解決動態加載問題后,他增加了循環,嘗試抓取前5頁數據(約100條)。他加入了time.sleep(random.uniform(1,3))在每次請求之間隨機休眠1-3秒,避免訪問過快觸發反爬。數據存儲也從單頁覆蓋改為追加模式。
接著,他用類似的方法分析當當網的結構,編寫了適配的爬蟲腳本。當當的反爬似乎弱一些,但頁面結構也略有不同,需要調整選擇器。
第六天:數據清洗與初步分析。
他成功抓取了京東156條、當當189條有效數據。但原始數據很“臟”:價格是字符串“¥39.80”,需要提取數字;評價數可能是“2萬+”,需要轉換為近似數值(如20000);店鋪名有冗余信息。他用pandas進行了清洗:
#價格清洗
df['價格']=df['價格'].str.replace('¥','').astype(float)
#評價數清洗(簡化處理,將“萬+”乘以10000)
defclean_mit(x)
if'萬'instr(x)
returnfloat(str(x).replace('萬+','').replace('萬',''))*10000
else
returnfloat(str(x).replace('+',''))
df['評價數']=df['評價數'].apply(clean_mit)
清洗后,他進行了快速的探索性分析:
1.價格分布:用df['價格'].describe()和直方圖查看。初中數學教輔價格主要集中在20-60元區間,均價約35元,但也有少數高端教輔(如競賽專題)價格超過100元。
2.銷量(評價數)與價格關系:繪制散點圖,發現評價數(粗略代表銷量)與價格呈微弱負相關,但高評價的爆款往往集中在30-50元這個“黃金價格帶”。
3.店鋪分析:發現銷量高的店鋪,除了官方自營,主要是幾家大型專營教輔的圖書專營店。個人小店鋪銷量普遍很低。
4.競品初步觀察:篩選出評價數最高的前20本書,查看其書名、特點。發現暢銷品集中在幾個系列(如“五年中考三年模擬”、“教材全解”、“實驗班”等),且名稱中常包含“必刷題”、“壓軸題”、“沖刺”等關鍵詞,緊扣應試痛點。
第七天:整合與洞察。
_c