利用Python模擬淘寶搜索以及初步數(shù)據(jù)分析

<p>本文講述如何利用Python模擬淘寶的搜索過程并對搜索結果進行初步的數(shù)據(jù)可視化分析攒砖。</p>

  • 搜索過程的模擬:淘寶的搜索頁面有兩種形式,一種形式是手機大類產品頁面谒臼,一種形式是其余產品頁面预烙。當然其余搜索占了總搜索類別的99%以上,本文會以其余為主進行淘寶搜索的模擬嘀略;
  • 初步數(shù)據(jù)可視化分析:對搜索回來的數(shù)據(jù),通過店鋪城市生成坐標數(shù)據(jù)乓诽,并將銷量帜羊、售價在地圖上標示出來。坐標數(shù)據(jù)的獲得要通過高德地圖的API插口鸠天,數(shù)據(jù)可視化為利用Plotly生成Buble Map讼育。

利用Python模擬搜索過程

<p>首先需要先對淘寶的模式進行標識,通過幾個關鍵詞搜索之后稠集,可以發(fā)現(xiàn)其地址的變化規(guī)律奶段,如下圖所示:</p>

淘寶搜索**脫皮綠豆**試試

<p>忽略掉q=脫皮綠豆后面的部分試試,在網址欄輸入(https://s.taobao.com/search?q=脫皮綠豆) 剥纷,發(fā)現(xiàn)可行忧饭。這樣就簡單了,后續(xù)就是解析生成頁筷畦、生成翻頁器、以及存儲生成數(shù)據(jù)即可刺洒。</p>

解析生成頁

<p>和之前的例子類似鳖宾,結合requests以及BeautifulSoup來完成頁面數(shù)據(jù)下載:</p>

def mainPaser(url):
    Headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36"}
    Response = requests.get(url, headers=Headers)
    Interial = BeautifulSoup(Response.content, 'lxml')
    pageConfig = Interial.find('script', text=re.compile('g_page_config'))
    return pageConfig.string

<p>繼續(xù)對淘寶的頁面進行Inspect,發(fā)現(xiàn)每一框的店鋪數(shù)據(jù)儲存在g_page_config中的auctions中逆航,并且g_page_config中的數(shù)據(jù)為json格式鼎文。</p>

淘寶搜索頁面
g_page_config以及auctions
獲取原始數(shù)據(jù)

<p>在Python中,json可以通過專門的解析器來完成因俐。通過其中的loads 和dumps 可以輕易的在json以及str之間做轉換拇惋。將str轉換為json格式,在通過pandas 的read_json獲取json中的數(shù)據(jù)信息抹剩。</p>
<p>每一框店鋪的數(shù)據(jù)涵括非常豐富的店鋪信息以及銷售信息撑帖,在這里僅收集寶貝分類(category)、評論數(shù)(comment_count)澳眷、寶貝位置(item_loc)胡嘿、店鋪名稱(nick)、寶貝名稱(raw_title)钳踊、原價格(reserve_price)衷敌、顯示價格(view_price)勿侯、銷量(view_sales)進行分析:</p>

neededColumns = ['category', 'comment_count', 'item_loc', 'nick', 'raw_title', 'view_price', 'view_sales']
PageConfig = re.search(r'g_page_config = (.*?);\n', pageConfig.string)
pageConfigJson = json.loads(gPageConfig.group(1))
pageItems = pageConfigJson['mods']['itemlist']['data']['auctions']
pageItemsJson = json.dumps(pageItems)
pageData = pd.read_json(pageItemsJson)
neededData = pageData[Paser.neededColumns]
整理生成數(shù)據(jù)

<p>接下來就是對得出的數(shù)據(jù)進行整理,我們先看看neededData的結構是如何缴罗,如下表所示:</p>

neededData

<p>其中item_loc是網店的地址助琐,可以看到直轄市是比較特殊的存在,將這一列改的省份名稱刪掉面氓,方法是單獨將這一列拿出來通過pandas.Series.str.split來處理兵钮,以空格為標識符,將該列的省份以及城市拆分為兩列侧但,結果如下圖矢空,通過pandas.DataFrame.fillna向左填充對None進行填充:</p>

fillna前

fillna后

<p>這樣就實現(xiàn)對item_loc列的修改,看回neededData那張圖禀横,最后一列view_sales中屁药,需要將每個單元格中付款兩個字刪去。需要采用pandas.Series.str.extract柏锄,結合正則表達式來處理酿箭。將數(shù)字文本拖出來之后,還需要通過astype函數(shù)將其轉化為int格式趾娃,并增加時間列缭嫡。最后該段數(shù)據(jù)整理的代碼,以及處理后的效果圖為:</p>

cityData = neededData['item_loc'].str.split(' ', expand = True)
cityData.fillna(method = 'pad', axis= 1, inplace= True)
neededData.loc[:,('item_loc')] = cityData[1]
neededData.loc[:,('view_sales')] = neededData['view_sales'].str.extract('([\d]*)([\w]*)').get(0)
neededData.loc[:,('view_sales')] = neededData['view_sales'].astype(int)
neededData['time'] = datetime.datetime.now().strftime('%Y%m%d%H')
處理結果
生成翻頁器

<p>最后就是生成翻頁器了抬闷,在剛剛的g_page_config中搜索pager試試:</p>

尋找翻頁器
尋找翻頁器

<p>將其中的\\u003d=以及\\u0026&作替換(我是通過字符替換處理妇蛀。。單應該存在更加方便的笤成,從編碼角度入手處理的方法评架。。求指教)炕泳,并更換一二三頁纵诞,發(fā)現(xiàn)網址最后的參數(shù)s分別為0,44培遵,88浙芙。結合上面第二張圖,可以猜到這個數(shù)字為單頁的店鋪總量籽腕,當頁面默認每頁的店鋪數(shù)為44的時候嗡呼,只需要更改該參數(shù)即可達到翻頁效果。</p>


數(shù)據(jù)可視化

<p>為了對將銷售數(shù)據(jù)以及評論數(shù)據(jù)放在地圖上皇耗,顯示區(qū)域集中情況晤锥,首先需要將城市信息轉化為坐標信息,這個時候需要用到高德地圖的API插口。而為了減少反復查詢的次數(shù)矾瘾,需要對坐標信息進行存儲女轿,即將位置數(shù)據(jù)存儲在sql中,邏輯是這樣:</p>

查詢框圖邏輯

<p>采用sqlite進行地理數(shù)據(jù)的存儲和查詢壕翩,對于查詢存在的數(shù)據(jù)直接輸出蛉迹,查詢不存在的數(shù)據(jù)需要通過高德地圖的行政區(qū)域查詢功能查詢。首先需要注冊自己的一個key放妈,并在對應賬號的控制版內增加Web服務API功能北救,使用過程中將key值以及設置信息用dict格式表示,并加載在requests的param中芜抒。查詢輸出的數(shù)據(jù)格式有兩種珍策,一種是json,一種是xml宅倒。這里輸出json攘宙,對json的字符串通過正則表達式將經緯度信息提取出來,提取出后存儲在數(shù)據(jù)文件中拐迁,并進行輸出蹭劈。 </p>

def getCenter(city):
    conn = sqlite3.connect('citydata.db')
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE IF NOT EXISTS CITYDATA(citycode text primary key , name text, latitude real, longitude real);")
    cursor.execute("SELECT latitude, longitude FROM CITYDATA WHERE name = ?", (city,))
    res = cursor.fetchall()
    if not res:
        payload = {
            ##yourkey = the key applied from amap.com
            'key':yourkey,'keywords':'',
            'subdistrict': '0','showbiz':False,'output':'json',
            }
        payload['keywords'] = city
        jsonData = requests.get('http://restapi.amap.com/v3/config/district?', params = payload)
        jsonText = jsonData.text
        center = re.search(r'\"([\d]*\.[\d]*)\,([\d]*\.[\d]*)\"', jsonText)
        cityCode = re.search(r'\"citycode\"\:\"(\d*)\"', jsonText)
        latitude = float(center.group(1))
        longitude =  float(center.group(2))
        cursor.execute("INSERT INTO CITYDATA VALUES(?, ?, ?, ?);", [cityCode.group(1), city, latitude, longitude])
        cursor.close()
        conn.commit()
        return latitude, longitude
    else:
        res = list(res[0])
        return res[0], res[1]

<p>經緯度數(shù)據(jù)獲得后,需要輸出到現(xiàn)有的dataFrame中线召,由于上述函數(shù)有兩個輸出铺韧,不能通過apply函數(shù)得出,需要結合zip以及map函數(shù)來實現(xiàn)雙輸出:</p>

neededData['latitude'], neededData['longitude'] = zip(*neededData['item_loc'].map(getCenter))
數(shù)據(jù)可視化

<p>dataFrame的可視化工具有很多缓淹,常用的有matplotlib哈打。但對于生成地理信息圖,似乎plotly更具有優(yōu)勢讯壶,并且經過優(yōu)化后料仗,plotly生成的圖像質量要更高。嘗試下對view_sales列進行可視化操作鹏溯,首先對該列進行排序:</p>

neededData.sort_values('view_sales', axis = 0, ascending = False, inplace=True)

<p>plotly在第一次使用的時候也需要設置自己的賬號信息,具體可以參考getting started淹仑,本機只要設置過一次賬號后丙挽,后面就可以不用再設置了。</p>

<p>首先需要對圖例進行設置:</p>

import plotly.plotly as py
length = len(newData)
limits = [(0, int(0.05*length)),(int(0.05*length), int(0.2*length)),(int(0.2*length),int(0.5*length)),(int(0.5*length),length)]
colors = ["#0A3854","#3779A3", "#1B85C6", "#C0DAEA"]
cities = []

<p>而后就是設置每個點的地理信息匀借、泡泡面積大小颜阐、泡泡顏色,并將dataFrame中的數(shù)據(jù)轉換為ployly可識別的格式中:</p>

for i in range(len(limits)):
    lim = limits[i]
    df_sub = newData[lim[0]:lim[1]]
    city = dict(
        type = 'scattergeo',
        locationmode = 'china',
        lon = df_sub['longitude'],
        lat = df_sub['latitude'],
        text = df_sub['nick'],
        marker = dict(
            size = df_sub['view_sales']/10,
            color = colors[i],
            line = dict(width = 0.5, color = '#000'),
            sizemode = 'area',
            opacity = 0.5
        ),
        name = "{0} - {1}".format(lim[0], lim[1])
    )
    cities.append(city)

<p>最后是對圖紙信息進行設定吓肋,包括標題凳怨,是否顯示圖例。由于ployly中已經包含有地圖信息,因此只需設定顯示區(qū)域(scope)肤舞,投影方式(projection)紫新,以及邊界線條顏色和邊界信息即可:</p>

layout = dict(
    title = Keyword + "的淘寶分布",
    showlegend = True,
    geo = dict(
        scope = "asia",
        projection = dict(type = 'mercator'),
        showland = True,
        landcolor = 'rgb(217, 217, 217)',
        subunitwidth=1,
        countrywidth=1,
        subunitcolor="rgb(255, 255, 255)",
        countrycolor="rgb(255, 255, 255)",
        lonaxis = dict(range = [newData['longitude'].min()-3, newData['longitude'].max() + 3]),
        lataxis = dict(range = [newData['latitude'].min()-0.5, newData['latitude'].max() + 0.5]),
    ),
)

<p>完成后,輸出保存即可:</p>

fig = dict(data = cities, layout = layout)
py.iplot(fig, validate = False)
脫皮綠豆的淘寶分布

總結

<p>本文基本實現(xiàn)了最初目的李剖,模擬了淘寶的搜索數(shù)據(jù)芒率,并初步對數(shù)據(jù)進行可視化。但該程序還有很多優(yōu)化的地方:</p>

  • 在搜索過程中篙顺,發(fā)現(xiàn)對于同一個關鍵詞會出現(xiàn)很多不同種類的東西偶芍,例如你搜索蘋果,可能會出現(xiàn)iphone也有可能出現(xiàn)能吃的蘋果德玫,不方便匪蟀;
  • 結合ML,實現(xiàn)深度的搜索宰僧,對同一個物品進行價格對比材彪,銷量對比,客戶評價對比撒桨,幫助客戶進行選擇查刻;
  • 可視化的意義沒有體現(xiàn)出來;
  • 本文中凤类,還有bug未完善穗泵,很多地方需要采用try來規(guī)避。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末谜疤,一起剝皮案震驚了整個濱河市佃延,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夷磕,老刑警劉巖履肃,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異坐桩,居然都是意外死亡尺棋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門绵跷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膘螟,“玉大人,你說我怎么就攤上這事碾局【2校” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵净当,是天一觀的道長内斯。 經常有香客問我蕴潦,道長,這世上最難降的妖魔是什么俘闯? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任潭苞,我火速辦了婚禮,結果婚禮上备徐,老公的妹妹穿的比我還像新娘萄传。我一直安慰自己,他們只是感情好蜜猾,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布秀菱。 她就那樣靜靜地躺著,像睡著了一般蹭睡。 火紅的嫁衣襯著肌膚如雪衍菱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天肩豁,我揣著相機與錄音脊串,去河邊找鬼。 笑死清钥,一個胖子當著我的面吹牛琼锋,可吹牛的內容都是我干的。 我是一名探鬼主播祟昭,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼缕坎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了篡悟?” 一聲冷哼從身側響起谜叹,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搬葬,沒想到半個月后荷腊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡急凰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年女仰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抡锈。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡疾忍,死狀恐怖,靈堂內的尸體忽然破棺而出企孩,到底是詐尸還是另有隱情锭碳,我是刑警寧澤袁稽,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布勿璃,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏补疑。R本人自食惡果不足惜歧沪,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望莲组。 院中可真熱鬧诊胞,春花似錦、人聲如沸锹杈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竭望。三九已至邪码,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咬清,已是汗流浹背闭专。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留旧烧,地道東北人影钉。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像掘剪,于是被迫代替她去往敵國和親平委。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內容