Python 爬蟲實戰五之模擬登錄淘寶并獲取所有訂單

      網友投稿 1852 2022-05-29

      經過多次嘗試,模擬登錄淘寶終于成功了,實在是不容易,淘寶的登錄加密和驗證太復雜了,煞費苦心,在此寫出來和大家一起分享,希望大家支持。

      溫馨提示

      更新時間,2016-02-01,現在淘寶換成了滑塊驗證了,比較難解決這個問題,以下的代碼沒法用了,僅作學習參考研究之用吧。

      本篇內容

      1. python 模擬登錄淘寶網頁 2. 獲取登錄用戶的所有訂單詳情 3. 學會應對出現驗證碼的情況 4. 體會一下復雜的模擬登錄機制

      探索部分成果

      1. 淘寶的密碼用了 AES 加密算法,最終將密碼轉化為 256 位,在 POST 時,傳輸的是 256 位長度的密碼。 2. 淘寶在登錄時必須要輸入驗證碼,在經過幾次嘗試失敗后最終獲取了驗證碼圖片讓用戶手動輸入來驗證。 3. 淘寶另外有復雜且每天在變的 ua 加密算法,在程序中我們需要提前獲取某一 ua 碼才可進行模擬登錄。 4. 在獲取最后的登錄 st 碼時,歷經了多次請求和正則表達式提取,且 st 碼只可使用一次。

      整體思路梳理

      1. 手動到瀏覽器獲取 ua 碼以及 加密后的密碼,只獲取一次即可,一勞永逸。 2. 向登錄界面發送登錄請求,POST 一系列參數,包括 ua 碼以及密碼等等,獲得響應,提取驗證碼圖像。 3. 用戶輸入手動驗證碼,重新加入驗證碼數據再次用 POST 方式發出請求,獲得響應,提取 J_Htoken。 4. 利用 J_Htoken 向 alipay 發出請求,獲得響應,提取 st 碼。 5. 利用 st 碼和用戶名,重新發出登錄請求,獲得響應,提取重定向網址,存儲 cookie。 6. 利用 cookie 向其他個人頁面如訂單頁面發出請求,獲得響應,提取訂單詳情。 是不是沒看懂?沒事,下面我將一點點說明自己模擬登錄的過程,希望大家可以理解。

      前期準備

      由于淘寶的 ua 算法和 aes 密碼加密算法太復雜了,ua 算法在淘寶每天都是在變化的,不過,這個內容你獲取之后一直用即可,經過測試之后沒有問題,一勞永逸。 那么 ua 和 aes 密碼怎樣獲取呢? 我們就從瀏覽器里面直接獲取吧,打開瀏覽器,找到淘寶的登錄界面,按 F12 或者瀏覽器右鍵審查元素。 在這里我用的是火狐瀏覽器,首先記得在瀏覽器中設置一下顯示持續日志,要不然頁面跳轉了你就看不到之前抓取的信息了。在這里截圖如下: 好,那么接下來我們就從瀏覽器中獲取 ua 和 aes 密碼 點擊網絡選項卡,這時都是空的,什么數據也沒有截取。這時你就在網頁上登錄一下試試吧,輸入用戶名啊,密碼啊,有必要時需要輸入驗證碼,點擊登錄。 等跳轉成功后,你就可以看到好多日志記錄了,點擊圖中的那一行 login.taobo.com,然后查看參數,你就會發現表單數據了,其中就包括 ua 還有下面的 password2,把這倆復制下來,我們之后要用到的。這就是我們需要的 ua 還有 aes 加密后的密碼。 恩,讀到這里,你應該獲取到了屬于自己的 ua 和 password2 兩個內容。

      輸入驗證碼并獲取 J_HToken

      經過博主本人親自驗證,有時候,在模擬登錄時你并不需要輸入驗證碼,它直接返回的結果就是前面所說的下一步用到的 J_Token,而有時候你則會需要輸入驗證碼,等你手動輸入驗證碼之后,重新請求登錄一次。 博主是邊寫程序邊更新文章的,現在寫完了是否有必要輸入驗證碼的檢驗以及在瀏覽器中呈現驗證碼。 代碼如下

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      88

      89

      90

      91

      92

      93

      94

      95

      96

      97

      98

      99

      100

      101

      102

      103

      104

      105

      106

      107

      108

      109

      110

      111

      112

      113

      114

      115

      116

      117

      118

      119

      120

      121

      122

      123

      124

      125

      126

      127

      128

      129

      130

      131

      132

      133

      134

      135

      136

      137

      138

      139

      140

      141

      142

      143

      144

      145

      146

      147

      148

      149

      150

      151

      __author__ = 'CQC'

      # -*- coding:utf-8 -*-

      import urllib

      import urllib2

      import cookielib

      import re

      import webbrowser

      #模擬登錄淘寶類

      class Taobao:

      #初始化方法

      def __init__(self):

      #登錄的URL

      self.loginURL = "https://login.taobao.com/member/login.jhtml"

      #代理IP地址,防止自己的IP被封禁

      self.proxyURL = 'http://120.193.146.97:843'

      #登錄POST數據時發送的頭部信息

      self.loginHeaders = {

      'Host':'login.taobao.com',

      'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0',

      'Referer' : 'https://login.taobao.com/member/login.jhtml',

      'Content-Type': 'application/x-www-form-urlencoded',

      'Connection' : 'Keep-Alive'

      }

      #用戶名

      self.username = 'cqcre'

      #ua字符串,經過淘寶ua算法計算得出,包含了時間戳,瀏覽器,屏幕分辨率,隨機數,鼠標移動,鼠標點擊,其實還有鍵盤輸入記錄,鼠標移動的記錄、點擊的記錄等等的信息

      self.ua = '191UW5TcyMNYQwiAiwTR3tCf0J/QnhEcUpkMmQ=|Um5Ockt0TXdPc011TXVKdyE=|U2xMHDJ+H2QJZwBxX39Rb1d5WXcrSixAJ1kjDVsN|VGhXd1llXGNaYFhkWmJaYl1gV2pIdUtyTXRKfkN4Qn1FeEF6R31TBQ==|VWldfS0TMw8xDjYWKhAwHiUdOA9wCDEVaxgkATdcNU8iDFoM|VmNDbUMV|V2NDbUMV|WGRYeCgGZhtmH2VScVI2UT5fORtmD2gCawwuRSJHZAFsCWMOdVYyVTpbPR99HWAFYVMpUDUFORshHiQdJR0jAT0JPQc/BDoFPgooFDZtVBR5Fn9VOwt2EWhCOVQ4WSJPJFkHXhgoSDVIMRgnHyFqQ3xEezceIRkmahRqFDZLIkUvRiEDaA9qQ3xEezcZORc5bzk=|WWdHFy0TMw8vEy0UIQE0ADgYJBohGjoAOw4uEiwXLAw2DThu9a==|WmBAED5+KnIbdRh1GXgFQSZbGFdrUm1UblZqVGxQa1ZiTGxQcEp1I3U=|W2NDEz19KXENZwJjHkY7Ui9OJQsre09zSWlXY1oMLBExHzERLxsuE0UT|XGZGFjh4LHQdcx5zH34DRyBdHlFtVGtSaFBsUmpWbVBkSmpXd05zTnMlcw==|XWdHFzl5LXUJYwZnGkI/VitKIQ8vEzMKNws3YTc=|XmdaZ0d6WmVFeUB8XGJaYEB4TGxWbk5yTndXa0tyT29Ta0t1QGBeZDI='

      #密碼,在這里不能輸入真實密碼,淘寶對此密碼進行了加密處理,256位,此處為加密后的密碼

      self.password2 = '7511aa68sx629e45de220d29174f1066537a73420ef6dbb5b46f202396703a2d56b0312df8769d886e6ca63d587fdbb99ee73927e8c07d9c88cd02182e1a21edc13fb8e140a4a2a4b5c253bf38484bd0e08199e03eb9bf7b365a5c673c03407d812b91394f0d3c7564042e3f2b11d156aeea37ad6460118914125ab8f8ac466f'

      self.post = post = {

      'ua':self.ua,

      'TPL_checkcode':'',

      'CtrlVersion': '1,0,0,7',

      'TPL_password':'',

      'TPL_redirect_url':'http://i.taobao.com/my_taobao.htm?nekot=udm8087E1424147022443',

      'TPL_username':self.username,

      'loginsite':'0',

      'newlogin':'0',

      'from':'tb',

      'fc':'default',

      'style':'default',

      'css_style':'',

      'tid':'XOR_1_000000000000000000000000000000_625C4720470A0A050976770A',

      'support':'000001',

      'loginType':'4',

      'minititle':'',

      'minipara':'',

      'umto':'NaN',

      'pstrong':'3',

      'llnick':'',

      'sign':'',

      'need_sign':'',

      'isIgnore':'',

      'full_redirect':'',

      'popid':'',

      'callback':'',

      'guf':'',

      'not_duplite_str':'',

      'need_user_id':'',

      'poy':'',

      'gvfdcname':'10',

      'gvfdcre':'',

      'from_encoding ':'',

      'sub':'',

      'TPL_password_2':self.password2,

      'loginASR':'1',

      'loginASRSuc':'1',

      'allp':'',

      'oslanguage':'zh-CN',

      'sr':'1366*768',

      'osVer':'windows|6.1',

      'naviVer':'firefox|35'

      }

      #將POST的數據進行編碼轉換

      self.postData = urllib.urlencode(self.post)

      #設置代理

      self.proxy = urllib2.ProxyHandler({'http':self.proxyURL})

      #設置cookie

      self.cookie = cookielib.LWPCookieJar()

      #設置cookie處理器

      self.cookieHandler = urllib2.HTTPCookieProcessor(self.cookie)

      #設置登錄時用到的opener,它的open方法相當于urllib2.urlopen

      self.opener = urllib2.build_opener(self.cookieHandler,self.proxy,urllib2.HTTPHandler)

      #得到是否需要輸入驗證碼,這次請求的相應有時會不同,有時需要驗證有時不需要

      def needIdenCode(self):

      #第一次登錄獲取驗證碼嘗試,構建request

      request = urllib2.Request(self.loginURL,self.postData,self.loginHeaders)

      #得到第一次登錄嘗試的相應

      response = self.opener.open(request)

      #獲取其中的內容

      content = response.read().decode('gbk')

      #獲取狀態嗎

      status = response.getcode()

      #狀態碼為200,獲取成功

      if status == 200:

      print u"獲取請求成功"

      #\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801這六個字是請輸入驗證碼的utf-8編碼

      pattern = re.compile(u'\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801',re.S)

      result = re.search(pattern,content)

      #如果找到該字符,代表需要輸入驗證碼

      if result:

      print u"此次安全驗證異常,您需要輸入驗證碼"

      return content

      #否則不需要

      else:

      print u"此次安全驗證通過,您這次不需要輸入驗證碼"

      return False

      else:

      print u"獲取請求失敗"

      #得到驗證碼圖片

      def getIdenCode(self,page):

      #得到驗證碼的圖片

      pattern = re.compile('

      }

      #用戶名

      self.username = 'cqcre'

      #ua字符串,經過淘寶ua算法計算得出,包含了時間戳,瀏覽器,屏幕分辨率,隨機數,鼠標移動,鼠標點擊,其實還有鍵盤輸入記錄,鼠標移動的記錄、點擊的記錄等等的信息

      self.ua = '191UW5TcyMNYQwiAiwTR3tCf0J/QnhEcUpkMmQ=|Um5Ockt0TXdPc011TXVKdyE=|U2xMHDJ+H2QJZwBxX39Rb1d5WXcrSixAJ1kjDVsN|VGhXd1llXGNaYFhkWmJaYl1gV2pIdUtyTXRKfkN4Qn1FeEF6R31TBQ==|VWldfS0TMw8xDjYWKhAwHiUdOA9wCDEVaxgkATdcNU8iDFoM|VmNDbUMV|V2NDbUMV|WGRYeCgGZhtmH2VScVI2UT5fORtmD2gCawwuRSJHZAFsCWMOdVYyVTpbPR99HWAFYVMpUDUFORshHiQdJR0jAT0JPQc/BDoFPgooFDZtVBR5Fn9VOwt2EWhCOVQ4WSJPJFkHXhgoSDVIMRgnHyFqQ3xEezceIRkmahRqFDZLIkUvRiEDaA9qQ3xEezcZORc5bzk=|WWdHFy0TMw8vEy0UIQE0ADgYJBohGjoAOw4uEiwXLAw2DThuOA==|WmBAED5+KnIbdRh1GXgFQSZbGFdrUm1UblZqVGxQa1ZiTGxQcEp1I3U=|W2NDEz19KXENZwJjHkY7Ui9OJQsre09zSWlXY1oMLBExHzERLxsuE0UT|XGZGFjh4LHQdcx5zH34DRyBdHlFtVGtSaFBsUmpWbVBkSmpXd05zTnMlcw==|XWdHFzl5LXUJYwZnGkI/VitKIQ8vEzMKNws3YTc=|XmdaZ0d6WmVFeUB8XGJaYEB4TGxWbk5yTndXa0tyT29Ta0t1QGBeZDI='

      #密碼,在這里不能輸入真實密碼,淘寶對此密碼進行了加密處理,256位,此處為加密后的密碼

      self.password2 = '7511aa6854629e45de220d29174f1066537a73420ef6dbb5b46f202396703a2d56b0312df8769d886e6ca63d587fdbb99ee73927e8c07d9c88cd02182e1a21edc13fb8e0a4a2a4b5c253bf38484bd0e08199e03eb9bf7b365a5c673c03407d812b91394f0d3c7564042e3f2b11d156aeea37ad6460118914125ab8f8ac466f'

      self.post = post = {

      'ua':self.ua,

      'TPL_checkcode':'',

      'CtrlVersion': '1,0,0,7',

      'TPL_password':'',

      'TPL_redirect_url':'http://i.taobao.com/my_taobao.htm?nekot=udm8087E1424147022443',

      'TPL_username':self.username,

      'loginsite':'0',

      'newlogin':'0',

      'from':'tb',

      'fc':'default',

      'style':'default',

      'css_style':'',

      'tid':'XOR_1_000000000000000000000000000000_625C4720470A0A050976770A',

      'support':'000001',

      'loginType':'4',

      'minititle':'',

      'minipara':'',

      'umto':'NaN',

      'pstrong':'3',

      'llnick':'',

      'sign':'',

      'need_sign':'',

      'isIgnore':'',

      'full_redirect':'',

      'popid':'',

      'callback':'',

      'guf':'',

      'not_duplite_str':'',

      'need_user_id':'',

      'poy':'',

      'gvfdcname':'10',

      'gvfdcre':'',

      'from_encoding ':'',

      'sub':'',

      'TPL_password_2':self.password2,

      'loginASR':'1',

      'loginASRSuc':'1',

      'allp':'',

      'oslanguage':'zh-CN',

      'sr':'1366*768',

      'osVer':'windows|6.1',

      'naviVer':'firefox|35'

      }

      #將POST的數據進行編碼轉換

      self.postData = urllib.urlencode(self.post)

      #設置代理

      self.proxy = urllib2.ProxyHandler({'http':self.proxyURL})

      #設置cookie

      self.cookie = cookielib.LWPCookieJar()

      #設置cookie處理器

      self.cookieHandler = urllib2.HTTPCookieProcessor(self.cookie)

      #設置登錄時用到的opener,它的open方法相當于urllib2.urlopen

      self.opener = urllib2.build_opener(self.cookieHandler,self.proxy,urllib2.HTTPHandler)

      #得到是否需要輸入驗證碼,這次請求的相應有時會不同,有時需要驗證有時不需要

      def needCheckCode(self):

      #第一次登錄獲取驗證碼嘗試,構建request

      request = urllib2.Request(self.loginURL,self.postData,self.loginHeaders)

      #得到第一次登錄嘗試的相應

      response = self.opener.open(request)

      #獲取其中的內容

      content = response.read().decode('gbk')

      #獲取狀態嗎

      status = response.getcode()

      #狀態碼為200,獲取成功

      if status == 200:

      print u"獲取請求成功"

      #\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801這六個字是請輸入驗證碼的utf-8編碼

      pattern = re.compile(u'\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801',re.S)

      result = re.search(pattern,content)

      print content

      #如果找到該字符,代表需要輸入驗證碼

      if result:

      print u"此次安全驗證異常,您需要輸入驗證碼"

      return content

      #否則不需要

      else:

      #返回結果直接帶有J_HToken字樣,表明直接驗證通過

      tokenPattern = re.compile('id="J_HToken"')

      tokenMatch = re.search(tokenPattern,content)

      if tokenMatch:

      print u"此次安全驗證通過,您這次不需要輸入驗證碼"

      return False

      else:

      print u"獲取請求失敗"

      return None

      #得到驗證碼圖片

      def getCheckCode(self,page):

      #得到驗證碼的圖片

      pattern = re.compile('

      result = re.search(pattern,content)

      #如果返回頁面包括了,驗證碼錯誤五個字

      if result:

      print u"驗證碼輸入錯誤"

      return False

      else:

      #返回結果直接帶有J_HToken字樣,說明驗證碼輸入成功,成功跳轉到了獲取HToken的界面

      tokenPattern = re.compile('id="J_HToken" value="(.*?)"')

      tokenMatch = re.search(tokenPattern,content)

      #如果匹配成功,找到了J_HToken

      if tokenMatch:

      print u"驗證碼輸入正確"

      print tokenMatch.group(1)

      return tokenMatch.group(1)

      else:

      #匹配失敗,J_Token獲取失敗

      print u"J_Token獲取失敗"

      return False

      except urllib2.HTTPError, e:

      print u"連接服務器出錯,錯誤原因",e.reason

      return False

      #程序運行主干

      def main(self):

      #是否需要驗證碼,是則得到頁面內容,不是則返回False

      needResult = self.needCheckCode()

      #請求獲取失敗,得到的結果是None

      if not needResult ==None:

      if not needResult == False:

      print u"您需要手動輸入驗證碼"

      idenCode = self.getCheckCode(needResult)

      #得到了驗證碼的鏈接

      if not idenCode == False:

      print u"驗證碼獲取成功"

      print u"請在瀏覽器中輸入您看到的驗證碼"

      webbrowser.open_new_tab(idenCode)

      J_HToken = self.loginWithCheckCode()

      print "J_HToken",J_HToken

      #驗證碼鏈接為空,無效驗證碼

      else:

      print u"驗證碼獲取失敗,請重試"

      else:

      print u"不需要輸入驗證碼"

      else:

      print u"請求登錄頁面失敗,無法確認是否需要驗證碼"

      taobao = Taobao()

      taobao.main()

      現在的運行結果是這樣的,我們已經可以得到 J_HToken 了,離成功又邁進了一步。 好,到現在為止,我們應該可以獲取到 J_HToken 的值啦。

      利用 J_HToken 獲取 st

      st 也是一個經計算得到的 code,可以這么理解,st 是淘寶后臺利用 J_HToken 以及其他數據經過計算之后得到的,可以利用 st 和用戶名直接用 get 方式登錄,所以 st 可以理解為一個秘鑰。這個 st 值只會使用一次,如果第二次用 get 方式登錄則會失效。所以它是一次性使用的。 下面 J_HToken 計算 st 的方法如下

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      #通過token獲得st

      def getSTbyToken(self,token):

      tokenURL = 'https://passport.alipay.com/mini_apply_st.js?site=0&token=%s&callback=stCallback6' % token

      request = urllib2.Request(tokenURL)

      response = urllib2.urlopen(request)

      #處理st,獲得用戶淘寶主頁的登錄地址

      pattern = re.compile('{"st":"(.*?)"}',re.S)

      result = re.search(pattern,response.read())

      #如果成功匹配

      if result:

      print u"成功獲取st碼"

      #獲取st的值

      st = result.group(1)

      return st

      else:

      print u"未匹配到st"

      return False

      直接利用 st 登錄

      得到 st 之后,基本上就大功告成啦,一段辛苦終于沒有白費,你可以直接構建 get 方式請求的 URL,直接訪問這個 URL 便可以實現登錄。

      1

      stURL = 'https://login.taobao.com/member/vst.htm?st=%s&TPL_username=%s' % (st,username)

      比如

      1

      https://login.taobao.com/member/vst.htm?st=1uynJELa4hKfsfWU3OjPJCw&TPL_username=cqcre

      直接訪問該鏈接即可實現登錄,不過我這個應該已經失效了吧~代碼在這先不貼了,剩下的一起貼了~

      獲取已買到的寶貝頁面

      已買到的寶貝的頁面地址是

      1

      http://buyer.trade.taobao.com/trade/itemlist/list_bought_items.htm

      另外還有頁碼的參數。 重新構建一個帶有 cookie 的 opener,將上面的帶有 st 的 URL 打開,保存它的 cookie,然后再利用這個 opener 打開已買到的寶貝的頁面,你就會得到已買到的寶貝頁面詳情了。

      1

      2

      3

      4

      5

      6

      #獲得已買到的寶貝頁面

      def getGoodsPage(self,pageIndex):

      goodsURL = 'http://buyer.trade.taobao.com/trade/itemlist/listBoughtItems.htm?action=itemlist/QueryAction&event_submit_do_query=1&pageNum=' + str(pageIndex)

      response = self.newOpener.open(goodsURL)

      page = response.read().decode('gbk')

      return page

      正則表達式提取信息 這是我的已買到的寶貝界面,審查元素可以看到,每一個寶貝都是 tbody 標簽包圍著。 我們現在想獲取訂單時間,訂單號,賣家店鋪名稱,寶貝名稱,原價,購買數量,最后付款多少,交易狀態這幾個量,具體就不再分析啦,正則表達式還不熟悉的同學請參考前面所說的正則表達式的用法,在這里,正則表達式匹配的代碼是

      1

      2

      3

      4

      5

      6

      7

      8

      9

      #u'\u8ba2\u5355\u53f7'是訂單號的編碼

      pattern = re.compile(u'dealtime.*?>(.*?).*?\u8ba2\u5355\u53f7.*?(.*?).*?shopname.*?title="(.*?)".*?baobei-name">.*?(.*?).*?'

      u'price.*?title="(.*?)".*?quantity.*?title="(.*?)".*?amount.*?em.*?>(.*?).*?trade-status.*?(.*?)',re.S)

      result = re.findall(pattern,page)

      for item in result:

      print '------------------------------------------------------------'

      print "購買日期:",item[0].strip(), '訂單號:',item[1].strip(),'賣家店鋪:',item[2].strip()

      print '寶貝名稱:',item[3].strip()

      print '原價:',item[4].strip(),'購買數量:',item[5].strip(),'實際支付:',item[6].strip(),'交易狀態',item[7].strip()

      最終代碼整理

      恩,你懂得,最重要的東西來了,經過博主 2 天多的奮戰,代碼基本就構建完成。寫了兩個類,其中提取頁面信息的方法我單獨放到了一個類中,叫 tool.py,類名為 Tool。 先看一下運行結果吧~ 最終代碼如下

      1

      tool.py

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      __author__ = 'CQC'

      # -*- coding:utf-8 -*-

      import re

      #處理獲得的寶貝頁面

      class Tool:

      #初始化

      def __init__(self):

      pass

      #獲得頁碼數

      def getPageNum(self,page):

      pattern = re.compile(u'

      .*?\u5171(.*?)\u9875',re.S)

      result = re.search(pattern,page)

      if result:

      print "找到了共多少頁"

      pageNum = result.group(1).strip()

      print '共',pageNum,'頁'

      return pageNum

      def getGoodsInfo(self,page):

      #u'\u8ba2\u5355\u53f7'是訂單號的編碼

      pattern = re.compile(u'dealtime.*?>(.*?).*?\u8ba2\u5355\u53f7.*?(.*?).*?shopname.*?title="(.*?)".*?baobei-name">.*?(.*?).*?'

      u'price.*?title="(.*?)".*?quantity.*?title="(.*?)".*?amount.*?em.*?>(.*?).*?trade-status.*?(.*?)',re.S)

      result = re.findall(pattern,page)

      for item in result:

      print '------------------------------------------------------------'

      print "購買日期:",item[0].strip(), '訂單號:',item[1].strip(),'賣家店鋪:',item[2].strip()

      print '寶貝名稱:',item[3].strip()

      print '原價:',item[4].strip(),'購買數量:',item[5].strip(),'實際支付:',item[6].strip(),'交易狀態',item[7].strip()

      1

      taobao.py

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      88

      89

      90

      91

      92

      93

      94

      95

      96

      97

      98

      99

      100

      101

      102

      103

      104

      105

      106

      107

      108

      109

      110

      111

      112

      113

      114

      115

      116

      117

      118

      119

      120

      121

      122

      123

      124

      125

      126

      127

      128

      129

      130

      131

      132

      133

      134

      135

      136

      137

      138

      139

      140

      141

      142

      143

      144

      145

      146

      147

      148

      149

      150

      151

      152

      153

      154

      155

      156

      157

      158

      159

      160

      161

      162

      163

      164

      165

      166

      167

      168

      169

      170

      171

      172

      173

      174

      175

      176

      177

      178

      179

      180

      181

      182

      183

      184

      185

      186

      187

      188

      189

      190

      191

      192

      193

      194

      195

      196

      197

      198

      199

      200

      201

      202

      203

      204

      205

      206

      207

      208

      209

      210

      211

      212

      213

      214

      215

      216

      217

      218

      219

      220

      221

      222

      223

      224

      225

      226

      227

      228

      229

      230

      231

      232

      233

      234

      235

      236

      237

      238

      239

      240

      241

      242

      243

      244

      245

      246

      247

      248

      249

      250

      251

      252

      253

      254

      255

      256

      257

      258

      259

      260

      261

      262

      263

      264

      265

      266

      267

      268

      269

      270

      271

      272

      273

      274

      275

      276

      277

      278

      279

      280

      281

      282

      283

      284

      285

      __author__ = 'CQC'

      # -*- coding:utf-8 -*-

      import urllib

      import urllib2

      import cookielib

      import re

      import webbrowser

      import tool

      #模擬登錄淘寶類

      class Taobao:

      #初始化方法

      def __init__(self):

      #登錄的URL

      self.loginURL = "https://login.taobao.com/member/login.jhtml"

      #代理IP地址,防止自己的IP被封禁

      self.proxyURL = 'http://120.193.146.97:843'

      #登錄POST數據時發送的頭部信息

      self.loginHeaders = {

      'Host':'login.taobao.com',

      'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0',

      'Referer' : 'https://login.taobao.com/member/login.jhtml',

      'Content-Type': 'application/x-www-form-urlencoded',

      'Connection' : 'Keep-Alive'

      }

      #用戶名

      self.username = 'cqcre'

      #ua字符串,經過淘寶ua算法計算得出,包含了時間戳,瀏覽器,屏幕分辨率,隨機數,鼠標移動,鼠標點擊,其實還有鍵盤輸入記錄,鼠標移動的記錄、點擊的記錄等等的信息

      self.ua = '191UW5TcyMNYQwiAiwTR3tCf0J/QnhEcUpkMmQ=|Um5Ockt0TXdPc011TXVKdyE=|U2xMHDJ+H2QJZwBxX39Rb1d5WXcrSixAJ1kjDVsN|VGhXd1llXGNaYFhkWmJaYl1gV2pIdUtyTXRKfkN4Qn1FeEF6R31TBQ==|VWldfS0TMw8xDjYWKhAwHiUdOA9wCDEVaxgkATdcNU8iDFoM|VmNDbUMV|V2NDbUMV|WGRYeCgGZhtmH2VScVI2UT5fORtmD2gCawwuRSJHZAFsCWMOdVYyVTpbPR99HWAFYVMpUDUFORshHiQdJR0jAT0JPQc/BDoFPgooFDZtVBR5Fn9VOwt2EWhCOVQ4WSJPJFkHXhgoSDVIMRgnHyFqQ3xEezceIRkmahRqFDZLIkUvRiEDaA9qQ3xEezcZORc5bzk=|WWdHFy0TMw8vEy0UIQE0ADgYJBohGjoAOw4uEiwXLAw2DThuOA==|WmBAED5+KnIbdRh1GXgFQSZbGFdrUm1UblZqVGxQa1ZiTGxQcEp1I3U=|W2NDEz19KXENZwJjHkY7Ui9OJQsre09zSWlXY1oMLBExHzERLxsuE0UT|XGZGFjh4LHQdcx5zH34DRyBdHlFtVGtSaFBsUmpWbVBkSmpXd05zTnMlcw==|XWdHFzl5LXUJYwZnGkI/VitKIQ8vEzMKNws3YTc=|XmdaZ0d6WmVFeUB8XGJaYEB4TGxWbk5yTndXa0tyT29Ta0t1QGBeZDI='

      #密碼,在這里不能輸入真實密碼,淘寶對此密碼進行了加密處理,256位,此處為加密后的密碼

      self.password2 = '7511aa6854629e45de220d29174f1066537a73420ef6dbb5b46f202396703a2d56b0312df8769d886e6ca63d587fdbb99ee73927e8c07d9c88cd02182e1a21edc13fb8e140a4a2a4b53bf38484bd0e08199e03eb9bf7b365a5c673c03407d812b91394f0d3c7564042e3f2b11d156aeea37ad6460118914125ab8f8ac466f'

      self.post = post = {

      'ua':self.ua,

      'TPL_checkcode':'',

      'CtrlVersion': '1,0,0,7',

      'TPL_password':'',

      'TPL_redirect_url':'http://i.taobao.com/my_taobao.htm?nekot=udm8087E1424147022443',

      'TPL_username':self.username,

      'loginsite':'0',

      'newlogin':'0',

      'from':'tb',

      'fc':'default',

      'style':'default',

      'css_style':'',

      'tid':'XOR_1_000000000000000000000000000000_625C4720470A0A050976770A',

      'support':'000001',

      'loginType':'4',

      'minititle':'',

      'minipara':'',

      'umto':'NaN',

      'pstrong':'3',

      'llnick':'',

      'sign':'',

      'need_sign':'',

      'isIgnore':'',

      'full_redirect':'',

      'popid':'',

      'callback':'',

      'guf':'',

      'not_duplite_str':'',

      'need_user_id':'',

      'poy':'',

      'gvfdcname':'10',

      'gvfdcre':'',

      'from_encoding ':'',

      'sub':'',

      'TPL_password_2':self.password2,

      'loginASR':'1',

      'loginASRSuc':'1',

      'allp':'',

      'oslanguage':'zh-CN',

      'sr':'1366*768',

      'osVer':'windows|6.1',

      'naviVer':'firefox|35'

      }

      #將POST的數據進行編碼轉換

      self.postData = urllib.urlencode(self.post)

      #設置代理

      self.proxy = urllib2.ProxyHandler({'http':self.proxyURL})

      #設置cookie

      self.cookie = cookielib.LWPCookieJar()

      #設置cookie處理器

      self.cookieHandler = urllib2.HTTPCookieProcessor(self.cookie)

      #設置登錄時用到的opener,它的open方法相當于urllib2.urlopen

      self.opener = urllib2.build_opener(self.cookieHandler,self.proxy,urllib2.HTTPHandler)

      #賦值J_HToken

      self.J_HToken = ''

      #登錄成功時,需要的Cookie

      self.newCookie = cookielib.CookieJar()

      #登陸成功時,需要的一個新的opener

      self.newOpener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.newCookie))

      #引入工具類

      self.tool = tool.Tool()

      #得到是否需要輸入驗證碼,這次請求的相應有時會不同,有時需要驗證有時不需要

      def needCheckCode(self):

      #第一次登錄獲取驗證碼嘗試,構建request

      request = urllib2.Request(self.loginURL,self.postData,self.loginHeaders)

      #得到第一次登錄嘗試的相應

      response = self.opener.open(request)

      #獲取其中的內容

      content = response.read().decode('gbk')

      #獲取狀態嗎

      status = response.getcode()

      #狀態碼為200,獲取成功

      if status == 200:

      print u"獲取請求成功"

      #\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801這六個字是請輸入驗證碼的utf-8編碼

      pattern = re.compile(u'\u8bf7\u8f93\u5165\u9a8c\u8bc1\u7801',re.S)

      result = re.search(pattern,content)

      #如果找到該字符,代表需要輸入驗證碼

      if result:

      print u"此次安全驗證異常,您需要輸入驗證碼"

      return content

      #否則不需要

      else:

      #返回結果直接帶有J_HToken字樣,表明直接驗證通過

      tokenPattern = re.compile('id="J_HToken" value="(.*?)"')

      tokenMatch = re.search(tokenPattern,content)

      if tokenMatch:

      self.J_HToken = tokenMatch.group(1)

      print u"此次安全驗證通過,您這次不需要輸入驗證碼"

      return False

      else:

      print u"獲取請求失敗"

      return None

      #得到驗證碼圖片

      def getCheckCode(self,page):

      #得到驗證碼的圖片

      pattern = re.compile('

      result = re.search(pattern,content)

      #如果返回頁面包括了,驗證碼錯誤五個字

      if result:

      print u"驗證碼輸入錯誤"

      return False

      else:

      #返回結果直接帶有J_HToken字樣,說明驗證碼輸入成功,成功跳轉到了獲取HToken的界面

      tokenPattern = re.compile('id="J_HToken" value="(.*?)"')

      tokenMatch = re.search(tokenPattern,content)

      #如果匹配成功,找到了J_HToken

      if tokenMatch:

      print u"驗證碼輸入正確"

      self.J_HToken = tokenMatch.group(1)

      return tokenMatch.group(1)

      else:

      #匹配失敗,J_Token獲取失敗

      print u"J_Token獲取失敗"

      return False

      except urllib2.HTTPError, e:

      print u"連接服務器出錯,錯誤原因",e.reason

      return False

      #通過token獲得st

      def getSTbyToken(self,token):

      tokenURL = 'https://passport.alipay.com/mini_apply_st.js?site=0&token=%s&callback=stCallback6' % token

      request = urllib2.Request(tokenURL)

      response = urllib2.urlopen(request)

      #處理st,獲得用戶淘寶主頁的登錄地址

      pattern = re.compile('{"st":"(.*?)"}',re.S)

      result = re.search(pattern,response.read())

      #如果成功匹配

      if result:

      print u"成功獲取st碼"

      #獲取st的值

      st = result.group(1)

      return st

      else:

      print u"未匹配到st"

      return False

      #利用st碼進行登錄,獲取重定向網址

      def loginByST(self,st,username):

      stURL = 'https://login.taobao.com/member/vst.htm?st=%s&TPL_username=%s' % (st,username)

      headers = {

      'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0',

      'Host':'login.taobao.com',

      'Connection' : 'Keep-Alive'

      }

      request = urllib2.Request(stURL,headers = headers)

      response = self.newOpener.open(request)

      content = response.read().decode('gbk')

      #檢測結果,看是否登錄成功

      pattern = re.compile('top.location = "(.*?)"',re.S)

      match = re.search(pattern,content)

      if match:

      print u"登錄網址成功"

      location = match.group(1)

      return True

      else:

      print "登錄失敗"

      return False

      #獲得已買到的寶貝頁面

      def getGoodsPage(self,pageIndex):

      goodsURL = 'http://buyer.trade.taobao.com/trade/itemlist/listBoughtItems.htm?action=itemlist/QueryAction&event_submit_do_query=1' + '&pageNum=' + str(pageIndex)

      response = self.newOpener.open(goodsURL)

      page = response.read().decode('gbk')

      return page

      #獲取所有已買到的寶貝信息

      def getAllGoods(self,pageNum):

      print u"獲取到的商品列表如下"

      for x in range(1,int(pageNum)+1):

      page = self.getGoodsPage(x)

      self.tool.getGoodsInfo(page)

      #程序運行主干

      def main(self):

      #是否需要驗證碼,是則得到頁面內容,不是則返回False

      needResult = self.needCheckCode()

      #請求獲取失敗,得到的結果是None

      if not needResult ==None:

      if not needResult == False:

      print u"您需要手動輸入驗證碼"

      checkCode = self.getCheckCode(needResult)

      #得到了驗證碼的鏈接

      if not checkCode == False:

      print u"驗證碼獲取成功"

      print u"請在瀏覽器中輸入您看到的驗證碼"

      webbrowser.open_new_tab(checkCode)

      self.loginWithCheckCode()

      #驗證碼鏈接為空,無效驗證碼

      else:

      print u"驗證碼獲取失敗,請重試"

      else:

      print u"不需要輸入驗證碼"

      else:

      print u"請求登錄頁面失敗,無法確認是否需要驗證碼"

      #判斷token是否正常獲取到

      if not self.J_HToken:

      print "獲取Token失敗,請重試"

      return

      #獲取st碼

      st = self.getSTbyToken(self.J_HToken)

      #利用st進行登錄

      result = self.loginByST(st,self.username)

      if result:

      #獲得所有寶貝的頁面

      page = self.getGoodsPage(1)

      pageNum = self.tool.getPageNum(page)

      self.getAllGoods(pageNum)

      else:

      print u"登錄失敗"

      taobao = Taobao()

      taobao.main()

      好啦,運行結果就是上面貼的圖片,可以成功獲取到自己的商品列表,前提是把你們的 用戶名,ua,password2 這三個設置好。 以上均為博主親身所敲,代碼寫的不好,謹在此貼出和大家一起分享經驗~小伙伴們試一下吧,希望對大家有幫助~

      Python

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Redis點贊業務的設計與實現(Redis鍵值設計)
      下一篇:【鯤鵬經典直播征文】+【鯤鵬應用使能套件】BoostKit虛擬化
      相關文章
      日本亚洲免费无线码| 亚洲成在人天堂一区二区| 亚洲级αV无码毛片久久精品| 亚洲乱妇老熟女爽到高潮的片| 亚洲国产精品成人精品软件| 亚洲国产人成网站在线电影动漫| 亚洲国产成人片在线观看无码| 伊人久久大香线蕉亚洲五月天| 国产亚洲欧洲Aⅴ综合一区| 激情无码亚洲一区二区三区| 337P日本欧洲亚洲大胆艺术图| 亚洲AV无码资源在线观看| 久久久久久亚洲精品无码| 国产精品亚洲精品爽爽| 日韩精品亚洲专区在线观看| 亚洲日韩涩涩成人午夜私人影院| 国产产在线精品亚洲AAVV| 小说专区亚洲春色校园| 国产亚洲午夜精品| 亚洲一区精品伊人久久伊人| 三上悠亚亚洲一区高清| 国产偷v国产偷v亚洲高清| 亚洲第一福利视频| 亚洲天天在线日亚洲洲精| 亚洲精品国产啊女成拍色拍| 亚洲一区二区免费视频| 中文无码亚洲精品字幕| 亚洲国产成人AV网站| 亚洲精品无码永久在线观看| 在线亚洲午夜理论AV大片| 亚洲AV永久无码精品| 亚洲高清中文字幕| 亚洲性线免费观看视频成熟| 亚洲成AV人片在WWW| 亚洲精品一级无码鲁丝片 | 亚洲国产精品人人做人人爽 | 亚洲av成人一区二区三区在线观看| 中文字幕亚洲情99在线| 中文字幕精品三区无码亚洲| 国产成人亚洲精品电影| 亚洲综合色成在线播放|