爬取淘寶商家貨物簡單銷售數據(銷量,價格,銷售地,貨物名稱)
養成好習慣:文中文末的小廣告點一點javascript
爬取淘寶店家數據信息
爬取淘寶商家貨物簡單銷售數據(銷量,價格,銷售地,貨物名稱)html
1、登陸淘寶,獲取Cookiesjava
2、輸入關鍵字,翻動頁碼,查看源碼以及迴應內容的變化。並請求數據python
3、分析數據網頁源碼,獲取數據nginx
4、存儲數據,並將數據按照銷量降序排列web
前天接一個爬取淘寶商家(自行車)信息的請求,要求數據按照其銷售量排行。正則表達式
完成該請求後,爬取數據(李寧衛衣)以下:chrome
接下來看如何實現的?shell
首先打開淘寶網:https://www.taobao.com/,在搜索欄輸入自行車,結果發現頁面轉跳到https://login.taobao.com/member/login.jhtml 淘寶登陸頁面,要求登陸才能進行關鍵字搜索獲取數據。(須要登陸的時候應當想到cookies)npm
cookies 及其用處:當咱們登陸某網站時,服務器會生成一個cookies,包含有用戶登陸等信息,與當前帳號綁定,瀏覽器將此cookies存儲到。下一次,瀏覽器帶着cookies訪問網站,就不須要在輸入帳號密碼。注意cookies是有時效性的。
因此,目標明確,第一步,獲取用戶登陸的cookies
1、登陸淘寶,獲取Cookies
須要登陸淘寶頁面獲取cookies,才能執行後續操做。而模擬登陸有兩種方法:
搞清淘寶登陸機制,修改參數登陸。
使用selenium調用webdriver模塊,模擬人真實的操做瀏覽器。
方法一:直接看源碼+備註
import requestsimport reimport jsonimport timeimport random
check_url = 'https://login.taobao.com/newlogin/account/check.do?appName=taobao&fromSite=0'headers = { 'origin':'https://login.taobao.com', 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36', # 標記了請求從什麼設備,什麼瀏覽器上發出}
session = requests.session()login_url = 'https://login.taobao.com/newlogin/login.do'
#本身手動登陸一次,在參數頁面把全部參數複製過來替換掉,看下圖Login_Data = { 'loginId': '****', 'password2': '*****', 'keepLogin': 'true', 'ua': '***', 'umidGetStatusVal': '255', 'screenPixel': '1536x864', 'navlanguage': 'zh-CN', 'navUserAgent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', 'navPlatform': 'Win32', 'appName': 'taobao', 'appEntrance': 'taobao_pc', '_csrf_token': '*****', 'umidToken': '****', 'hsiz': '****', 'bizParams':'', 'style': 'default', 'appkey': '00000000', 'from': 'tbTop', 'isMobile': 'false', 'lang': 'zh_CN', 'returnUrl': 'https://www.taobao.com/', 'fromSite': '0',}login_res = session.post(login_url,headers=headers,data=Login_Data) #帶着這些參數再登陸一次爬取數據
#獲取st碼申請地址token_json = login_res.json()st_url = token_json['content']['data']['asyncUrls'][0] #st碼的申請地址print('驗證用戶名和密碼成功')
#經過st碼申請地址獲取st碼st_res = requests.get(st_url,headers=headers)st_code_text = st_res.textst_code = st_code_text[579:-270] #獲取st碼,本身發現的規律,能夠這麼提取,也能夠使用正則表達式print('獲取st碼成功,st碼:{}'.format(st_code))
#獲取登陸跳轉連接res_st = session.get('https://login.taobao.com/member/vst.htm?st={}'.format(st_code) , headers=headers)my_taobao = re.search(r'top.location.href = "(.*?)"', res_st.text)print('登陸淘寶成功,跳轉連接:{}'.format(my_taobao.group(1)))my_taobao_url = my_taobao.group(1)
#登陸res_login = session.get(my_taobao_url, headers=headers)nick_name = re.search(r'<input id="mtb-nickname" type="hidden" value="(.*?)"/>', res_login.text)print('登陸淘寶成功,你的用戶名是:{}'.format(nick_name.group(1)))username = nick_name.group(1)
# 獲取cookies,將cookies轉成字典,再將字典轉成字符串,保存到文件夾中cookies_ditc = requests.utils.dict_from_cookiejar(session.cookies)cookies_str = json.dumps(cookies_ditc)f = open(r'C:\Users\13426\Desktop\cookies.txt','w',encoding='utf-8')f.write(cookies_str)print(cookies_str) #cookies,具備時效性。print('cookie已經完成序列化') f.close()
在自行登陸之後,把參數都複製到Data裏替換掉代碼中的data就能夠。
方法二:使用selenium調用webdriver模塊(本身寫的,因此解釋詳細點)
前提是安裝了Chorm driver插件
Chorm插件下載地址:http://npm.taobao.org/mirrors/chromedriver/2.44/
下載完成後,解壓到python根目錄下便可。
driver能夠模擬人在目標欄目輸入,也能夠模擬人對按鈕進行點擊。
對登陸頁面以及源碼進行分析:發現:
賬號輸入框對應:<input name="fm-login-id" type="text" class="fm-text" id="fm-login-id" tabindex="1" aria-label="會員名/郵箱/手機號" placeholder="會員名/郵箱/手機號" autocapitalize="off">密碼輸入框對應:<input name="fm-login-password" type="password" class="fm-text" id="fm-login-password" tabindex="2" aria-label="請輸入登陸密碼" placeholder="請輸入登陸密碼" maxlength="40" autocapitalize="off">登陸按鈕欄目對應:<button type="submit" tabindex="3" class="fm-button fm-submit password-login">登陸</button>
因此,代碼以下:在帳號密碼框裏輸入內容,點擊登陸進行登陸
from selenium import webdriver#調用webdriver模塊
driver = webdriver.Chrome()#設置引擎爲Chrome,模擬真實地打開一個瀏覽器driver.get('https://login.taobao.com/member/login.jhtml') #打開這個連接time.sleep(1) #等待一秒鐘,模擬真人操做
## 運行代碼以前輸入本身的帳號和密碼user = driver.find_element_by_name('fm-login-id')user.send_keys('這裏輸入本身的帳號') #在fm-login-id對應框中輸入帳號time.sleep(1)assistant = driver.find_element_by_name('fm-login-password')assistant.send_keys('這裏輸入本身的密碼')time.sleep(1)submit = driver.find_element_by_class_name('fm-btn') #點擊登陸按鈕submit.click()#登陸time.sleep(5)cookie_list = driver.get_cookies() #登陸之後獲取cookiecookies = {}print(len(cookie_list))for cookie in cookie_list: cookies[cookie['name']] = cookie['value'] #將cookies字典化print("已經成功的獲取到用戶登陸的cookies")print(cookies)driver.close()
注意,有時候登陸時須要滑動滑塊,手動滑動登陸便可。
到此用戶操做所用cookies的已經獲取,這時候就能夠搜索關鍵字了
2、輸入關鍵字,翻動頁碼,查看源碼以及迴應內容的變化。並請求數據
進入搜索頁:https://s.taobao.com/search? 輸入關鍵字,觀察url變化
咱們發現q參數對應着搜索內容。而後翻動頁面,來到第二頁,觀察url變化,發現變化的有s參數
研究多個頁面發現,url須要修改的參數只有q與s。
在翻頁的過程當中,發現咱們所須要的內容在Response的第0個迴應中,即存在於Element中,因此只要獲取到該網頁的源碼,就能夠獲取到數據。
因此使用https://s.taobao.com/search?q=自行車&s=88 這個格式(q表示搜索的關鍵字,s*44表明頁數)的連接就能夠訪問帶有數據的源碼。
因此代碼以下:
headers = {'Host':'s.taobao.com', 'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Accept-Encoding':'gzip, deflate, br', 'Connection':'keep-alive' }list_url = 'http://s.taobao.com/search?q=%(key)s&ie=utf8&s=%(pnum)d'
for i in range(Page): pnum = i*44 url = list_url%{'key':key,'pnum':pnum} print(url) res = requests.get(url,headers=headers,cookies=cookies) #帶有前面獲取的cookies
3、分析數據網頁源碼,獲取數據
這是我爬取的一個李寧衛衣的網頁源碼,發現重要信息保存在一個大字典:g_page_config中
因此咱們能夠經過正則表達式獲取這個大字典,而後逐一提取各數據。或者直接正則各數據提取,咱們採用第二種方法。
#建立正則表達式titles = '"raw_title":"(.*?)"' #標題locations = '"item_loc":"(.*?)"' #銷售地sales = '"view_sales":"(.*?)人付款"' #銷售量comments = '"comment_count":"(.*?)"'#評論數prices = '"view_price":"(.*?)"' #銷售價格nids = '"nid":"(.*?)"' #這裏須要nid,是由於商品的連接是須要這個參數的
#res.text表示網頁源碼,在其中匹配正則title = re.findall(titles,res.text)location = re.findall(locations,res.text)sale = re.findall(sales,res.text)comment = re.findall(comments,res.text)price = re.findall(prices,res.text)nid = re.findall(nids,res.text)
到這裏已經把全部有效數據存儲到title,location等變量中。它們均爲字符串列表
4、存儲數據,並將數據按照銷量降序排列
使用csv保存數據
csv_file = open(r'文件保存路徑','w',newline='',encoding='utf-8-sig')writer = csv.writer(csv_file)writer.writerow(['商品名稱','銷售地','銷售量','評論數','銷售價格','商品連接'])#後續寫入便可
由於要求數據要根據銷量降序排列,而銷量數據格式爲字符串。分析源碼,發現源碼中銷量的表示通常有’8000+’、‘1.6萬+’、‘784’這幾種表示。即若是銷量小於10000,則按照 ‘具體數字’ 或 ‘具體數字+’ 這樣表示,如’845’、‘3500+’,若是數據大於一萬,則會在後續加個萬字, 如’1.6萬+’,‘5.8萬’,強轉爲float時須要作判斷:
因此,經過條件判斷語句和if else判斷:
sale[j] = sale[j] if sale[j][-1] !='+' else sale[j][:-1] #判斷最後一位是否是+,若是是,就刪掉if sale[j][-1] == '萬': data.append([ title[j],location[j],float(sale[j][:-1])*10000,comment[j],price[j],goods_url ]) #若是最後一位是萬,去掉最後一位,乘以10000便可else: data.append([ title[j],location[j],float(sale[j]),comment[j],price[j],goods_url ])
data.sort(key=itemgetter(2)) #按照第3個元素,即銷量進行排序data.reverse()#按照銷量進行排序
還有一個發現就是,商品的連接與nid是有關係的,具體關係以下:
goods_url = 'https://item.taobao.com/item.htm?id='+nid[j]+'&ns=1&abbucket=19#detail'
到此代碼已經分析完畢,源碼以下,登陸時修改本身的帳號密碼,以及文件的保存路徑便可:
import timeimport requestsimport jsonimport refrom selenium import webdriver#調用webdriver模塊import csvfrom operator import itemgetter## 在這裏設置下爬取結果文件保存的路徑csv_file = open(r'C:\Users\13426\Desktop\demo.csv','w',newline='',encoding='utf-8-sig')writer = csv.writer(csv_file)
driver = webdriver.Chrome()#設置引擎爲Chrome,模擬真實地打開一個瀏覽器driver.get('https://login.taobao.com/member/login.jhtml')time.sleep(1)
## 運行代碼以前輸入本身的帳號和密碼user = driver.find_element_by_name('fm-login-id')user.send_keys('輸入本身的帳號')time.sleep(1)assistant = driver.find_element_by_name('fm-login-password')assistant.send_keys('輸入本身的密碼')time.sleep(1)submit = driver.find_element_by_class_name('fm-btn')submit.click()#登陸time.sleep(5)cookie_list = driver.get_cookies()cookies = {}print(len(cookie_list))for cookie in cookie_list: cookies[cookie['name']] = cookie['value']print("已經成功的獲取到用戶登陸的cookies")print(cookies)driver.close()
headers = {'Host':'s.taobao.com', 'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0', 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Accept-Encoding':'gzip, deflate, br', 'Connection':'keep-alive' }list_url = 'http://s.taobao.com/search?q=%(key)s&ie=utf8&s=%(pnum)d'
titles = '"raw_title":"(.*?)"' #標題locations = '"item_loc":"(.*?)"' #銷售地sales = '"view_sales":"(.*?)人付款"' #銷售量comments = '"comment_count":"(.*?)"'#評論數prices = '"view_price":"(.*?)"' #銷售價格nids = '"nid":"(.*?)"' #這裏須要nid,是由於商品的連接是須要這個參數的 writer.writerow(['商品名稱','銷售地','銷售量','評論數','銷售價格','商品連接'])
key = input('輸入想要爬取的商品名稱:')Page = 5 # 爬取的頁數 ,能夠自行修改data = []
for i in range(Page): pnum = i*44 url = list_url%{'key':key,'pnum':pnum} print(url) res = requests.get(url,headers=headers,cookies=cookies) html = res.text
title = re.findall(titles,html) location = re.findall(locations,html) sale = re.findall(sales,html) comment = re.findall(comments,html) price = re.findall(prices,html) nid = re.findall(nids,html) for j in range(len(title)): goods_url = 'https://item.taobao.com/item.htm?id='+nid[j]+'&ns=1&abbucket=19#detail' sale[j] = sale[j] if sale[j][-1] !='+' else sale[j][:-1] if sale[j][-1] == '萬': data.append([ title[j],location[j],float(sale[j][:-1])*10000,comment[j],price[j],goods_url ]) #若是最後一位是萬,去掉最後一位,乘以10000便可 else: data.append([ title[j],location[j],float(sale[j]),comment[j],price[j],goods_url ])
print('-------Page%s 已經抓取完畢!--------\n\n'%(i+1)) time.sleep(2)data.sort(key=itemgetter(2))data.reverse()#按照銷量進行排序 for j in range(len(data)): writer.writerow(data[j])
正文結束!!!!
來一杯飲料放鬆放鬆
歡迎關注公衆號:Python爬蟲數據分析挖掘,方便及時閱讀最新文章
記錄學習python的點點滴滴;
回覆【開源源碼】免費獲取更多開源項目源碼;
公衆號每日更新python知識和【免費】工具;
本文已同步到【開源中國】、【騰訊雲社區】、【CSDN】;
本文分享自微信公衆號 - Python爬蟲數據分析挖掘(zyzx3344)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。