Last 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属性
部分代码如下: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笔交易记录
遗留问题会在学习更多之后解决