2ff34e647e2e3cdfd8dca593e17d9b0a.pngLast updated on

本文仅学习交流使用,记录学习用webdriver模拟登录支付宝保存cookie,再用requests.session()加载cookie并用Xpath获取订单信息,将订单存储到MySQL数据库中的过程。

本机主要运行环境及库Arch Linux

webdriver(Chrome或者FireFox)

Python3.6

selenium 库

json 库

requests 库

lxml 库

MySQLdb 库

确保本机具有或类似的运行条件,webdriver 安装方法在selenium模拟登录163邮箱中已经提到。

selenium、json、requests、lxml库都可以通过python的包管理工具PyPI安装。

Python2.x 的版本通过pip安装mysql-python 来连接MySQL数据库,Python3.x则需要通过pip安装mysqlclient来实现Python和MySQL的连接。

获取cookie

我们用webdriver登录支付宝来获取cookie,并用json使数据持久化。

首先获取支付宝登录页面的URL:

https://auth.alipay.com/login/index.htm?goto=https%3A%2F%2Flab.alipay.com%2Fuser%2Fi.htm

通过Chrome开发者工具获取用户名文本框的id属性、密码文本框的name属性、和登录按钮的id属性

alipay1.gif

部分代码如下:1

2

3

4

5

6

7

8

9

10

11

12

13

14driver = webdriver.Firefox()

driver.maximize_window()

driver.get('https://auth.alipay.com/login/index.htm?goto=https%3A%2F%2Fmy.alipay.com%2Fportal%2Fi.htm')

time.sleep(2)

driver.find_element_by_id('J-input-user').send_keys('你的支付宝用户名') # 输入用户名

driver.find_element_by_name('password_rsainput').send_keys('你的支付宝密码') # 输入密码

driver.find_element_by_id('J-login-btn').click() # 点击登录按钮

# 获取cookie,并保存到本地

cookies = driver.get_cookies()

with open('cookies','w') as f:

json.dump(cookies, f)

f.close()

driver.close()

设置cookie

要用requests.session()请求网页进行爬取,所以我们就直接加载本地的cookie来请求网页

部分代码如下:1

2

3

4

5

6with ('cookies', 'r') as f:

cookies= json.load(f)

for cookie in cookies:

c = {cookie['name']: cookie['value']}

session.cookies.update(c)

获取数据

采用lxml来解析网页,然后通过xpath来找到相应的数据,最后存储到各自list中,为的是之后存储到数据库方便

部分代码如下: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# 获取交易记录界面

html = self.session.get('https://consumeprod.alipay.com/record/standard.htm')

# 用lxml解析html

selector= etree.HTML(html.text)

# 获取最近20个交易数据

for i in range(1,21):

# 获取流水号

number = selector.xpath('//*[@id="J-tradeNo-'+str(i)+

number_list.append(number[0].strip())

# 获取交易时间

time = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[2]/p[1]/text()')

time_list.append(time[0].strip())

# 获取具体内容

try:

# 交易成功的内容

content = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[3]/p[1]/a/text()')

content_list.append(content[0].strip())

except:

# 交易失败的内容

content = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[3]/p[1]/text()')

content_list.append(content[0].strip())

# 获取金额变动

money = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[4]/span/text()')

money_list.append(money[0].strip())

# 获取交易状态

state = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[6]/p[1]/text()')

state_list.append(state[0].strip())

存储数据

将存储到list中的数据,存储到mysql中

部分代码如下:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17# 连接数据库

db = MySQLdb.connect('localhost', 'root', '数据库密码', '数据库')

# 获取游标

cursor = db.cursor()

for i in range(20):

# sql 插入语句,插入到alipay表中

sql = "INSERT IGNORE INTO alipay(NUMBER,DATE,CONTENT,MONEY,STATE) VALUES ('%s','%s','%s','%s','%s')" % (number_list[i],time_list[i],content_list[i],money_list[i],state_list[i])

try:

# 执行sql语句

cursor.execute(sql)

# 提交到数据库

db.commit()

except:

# 失败回滚

db.rollback()

# 关闭数据库连接

db.close()

完整代码

将代码进行了封装,增加了对加载cookie后登录状态的确认

完整代码如下: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# -*- coding=utf-8 -*-

from selenium import webdriver

import time

import json

import requests

from lxml import etree

import MySQLdb

class AlipaySpider(object):

def __init__(self):

self.headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36'}

self.session = requests.Session()

self.session.headers = self.headers

self.number_list = []

self.time_list = []

self.content_list = []

self.money_list = []

self.state_list = []

# 用webdriver 获取cookie

def save_cookies(self):

driver = webdriver.Firefox()

driver.maximize_window()

driver.get('https://auth.alipay.com/login/index.htm?goto=https%3A%2F%2Fmy.alipay.com%2Fportal%2Fi.htm')

# 等待2秒

time.sleep(2)

driver.find_element_by_id('J-input-user').send_keys('你的支付宝用户名')

driver.find_element_by_name('password_rsainput').send_keys('你的支付宝密码')

driver.find_element_by_id('J-login-btn').click()

# 获取cookie,并保存到本地

cookies = driver.get_cookies()

with open('cookies','w') as f:

json.dump(cookies, f)

f.close()

driver.close()

# 设置cookie

def set_cookies(self):

# 从文件中获取cookie

with open('cookies', 'r') as f:

cookies = json.load(f)

# 将json存储的cookie 转化为dict,并更新session的coookie

for cookie in cookies:

c = {cookie['name']: cookie['value']}

self.session.cookies.update(c)

# 判断是否已经登录

def aready_login(self):

self.set_cookies()

html_code = self.session.get('https://custweb.alipay.com/account/index.htm',allow_redirects=False).status_code

if html_code == 200:

return True

else:

return False

# 获取数据

def get_data(self):

# 获取交易记录界面

html = self.session.get('https://consumeprod.alipay.com/record/standard.htm')

# 用lxml解析html

selector= etree.HTML(html.text)

# 获取最近20个交易数据

for i in range(1,21):

# 获取流水号

number = selector.xpath('//*[@id="J-tradeNo-'+str(i)+

self.number_list.append(number[0].strip())

# 获取交易时间

time = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[2]/p[1]/text()')

self.time_list.append(time[0].strip())

# 获取具体内容

try:

# 交易成功的内容

content = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[3]/p[1]/a/text()')

self.content_list.append(content[0].strip())

except:

# 交易失败的内容

content = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[3]/p[1]/text()')

self.content_list.append(content[0].strip())

# 获取金额变动

money = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[4]/span/text()')

self.money_list.append(money[0].strip())

# 获取交易状态

state = selector.xpath('//*[@id="J-item-'+str(i)+'"]/td[6]/p[1]/text()')

self.state_list.append(state[0].strip())

# 存储数据

def save_data(self):

# 连接数据库

db = MySQLdb.connect('localhost', 'root', '密码', '数据库')

# 获取游标

cursor = db.cursor()

for i in range(20):

# sql 插入语句,插入到alipay表中

sql = "INSERT IGNORE INTO alipay(NUMBER,DATE,CONTENT,MONEY,STATE) VALUES ('%s','%s','%s','%s','%s')" % (self.number_list[i],self.time_list[i],self.content_list[i],self.money_list[i],self.state_list[i])

try:

# 执行sql语句

cursor.execute(sql)

# 提交到数据库

db.commit()

except:

# 失败回滚

db.rollback()

# 关闭数据库连接

db.close()

def total_crawl(self):

self.save_cookies() # 保存cookie

self.set_cookies() # 设置cookie

self.get_data() # 爬取数据

self.save_data() # 保存数据

def crawl(self):

self.get_data() # 爬取数据

self.save_data() # 保存数据

if __name__ == "__main__":

spider = AlipaySpider()

if spider.aready_login() == True:

spider.crawl()

else:

spider.total_crawl()

总结

通过本次的学习,有2点不足之处。有时由于多次访问支付宝页面,导致登录页面有验证码,这样获取到的cookie就不成功了,需要再次请求,直到没有验证码,才能获取到cookie

数据爬取时,只能爬取到最近的20笔交易记录

遗留问题会在学习更多之后解决

Logo

更多推荐