├── QQ图片20160909000938.png ├── QQ图片20160925204723.png ├── README.md ├── __init__.py ├── __pycache__ ├── __init__.cpython-35.pyc ├── coupon.cpython-35.pyc ├── jd_review.cpython-35.pyc ├── stocks.cpython-35.pyc └── timing.cpython-35.pyc ├── cookies.txt ├── coupon.py ├── jd_review.py ├── main.py ├── password.txt ├── stocks.py ├── timing.py └── urls.txt /QQ图片20160909000938.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csu-feizao/get_coupon/c56871f63eaa4f211ef6c4c41d3994ac790b7e1c/QQ图片20160909000938.png -------------------------------------------------------------------------------- /QQ图片20160925204723.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csu-feizao/get_coupon/c56871f63eaa4f211ef6c4c41d3994ac790b7e1c/QQ图片20160925204723.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 程序介绍: 2 | 3 | 1.本程序以京东领取优惠券为例学习requests模块,仅作交流学习使用,请勿用于 4 | 其它非法用途,程序作者不承担任何法律责任。 5 | 6 | 7 | 2.领券功能: 8 | 9 | 2.1 优惠券链接存放在urls.txt,一行一个链接。 10 | 11 | 2.2 用户cookie存放在cookies.txt,一行一个cookie。(cookie需要自己浏览器登录 12 | 账户后自行提取,这里不提供。若cookie长度超出1行,请考虑使用隐身模式登录 13 | 提取cookie,或者手动删除cookie中一些不必要的内容) 14 | 15 | 2.3 使用前请先关闭fiddler软件,否则会报出SSL错误 16 | 17 | 18 | 3.京豆兑换券功能: 19 | 20 | 3.1 用户密码存放在password.txt中,并保证与cookies.txt的数目和顺序相同,否则报错 21 | 22 | 23 | 4.软件可选择单个用户执行亦可选择全部用户,可单次提交亦可循环提交,定时提交等。 24 | 25 | 5.返回领取结果 26 | 27 | 6.查询商品价格及库存 28 | 29 | 7.查询商品评价并存入mysql数据库 -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csu-feizao/get_coupon/c56871f63eaa4f211ef6c4c41d3994ac790b7e1c/__init__.py -------------------------------------------------------------------------------- /__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csu-feizao/get_coupon/c56871f63eaa4f211ef6c4c41d3994ac790b7e1c/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/coupon.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csu-feizao/get_coupon/c56871f63eaa4f211ef6c4c41d3994ac790b7e1c/__pycache__/coupon.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/jd_review.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csu-feizao/get_coupon/c56871f63eaa4f211ef6c4c41d3994ac790b7e1c/__pycache__/jd_review.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/stocks.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csu-feizao/get_coupon/c56871f63eaa4f211ef6c4c41d3994ac790b7e1c/__pycache__/stocks.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/timing.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csu-feizao/get_coupon/c56871f63eaa4f211ef6c4c41d3994ac790b7e1c/__pycache__/timing.cpython-35.pyc -------------------------------------------------------------------------------- /cookies.txt: -------------------------------------------------------------------------------- 1 | this is the first user's cookie 2 | this is the second user's cookie 3 | this is the third user's cookie 4 | ... -------------------------------------------------------------------------------- /coupon.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import time,threading 3 | import re 4 | from multiprocessing import Process,Pool 5 | from get_coupon import timing 6 | 7 | 8 | class MyInfo(object): 9 | def __init__(self): 10 | self.urls=self.get_userdata('C:\\Users\肥皂\Desktop\\url.txt') 11 | self.cookies=self.get_userdata('C:\\Users\肥皂\Desktop\\ck.txt') 12 | 13 | def get_userdata(self,file_url): 14 | with open(file_url,'r') as f1: 15 | my_lists=f1.readlines() 16 | data=tuple([flist.strip() for flist in my_lists]) 17 | return data 18 | 19 | def set_url(self,m): 20 | self.url=self.urls[m-1] 21 | 22 | def set_headers(self,cookie): 23 | self.headers={ 24 | 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 25 | 'Accept-Encoding':'gzip, deflate, sdch', 26 | 'Accept-Language':'zh-CN,zh;q=0.8', 27 | 'Connection':'keep-alive', 28 | 'Cookie':cookie, 29 | 'Cache-Control':'max-age=0', 30 | 'Upgrade-Insecure-Requests':'1', 31 | 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2743.116 Safari/537.36' 32 | } 33 | 34 | def pool_loop(self,loop_times,function): 35 | pool=Pool(4) 36 | for i in range(loop_times): 37 | pool.apply_async(function) 38 | pool.close() 39 | pool.join() 40 | 41 | 42 | class GetCoupon(MyInfo): 43 | def get_page(self): 44 | s=requests.session() 45 | s.headers=self.headers 46 | try: 47 | r=s.get(self.url,timeout=10) 48 | except requests.TooManyRedirects: 49 | print('cookie失效,原因不明(可能是半白号,访问过快触发京东保护机制),请重新提取cookie') 50 | except (requests.ConnectTimeout,requests.ReadTimeout): 51 | print('超时重试中,若依然如此请检查网络') 52 | except: 53 | pass 54 | else: 55 | cer=re.compile('

(.*)

',flags=0) 56 | strlist=cer.findall(r.text) 57 | if not strlist: 58 | print('未知错误') 59 | else: 60 | print(strlist[0]) 61 | 62 | def one_get(self,n): 63 | self.set_headers(self.cookies[n-1]) 64 | self.get_page() 65 | 66 | def loop_one_get(self,n,loop_times): 67 | self.set_headers(self.cookies[n-1]) 68 | self.pool_loop(loop_times,self.get_page) 69 | 70 | def all_get(self): 71 | for cookie in self.cookies: 72 | self.set_headers(cookie) 73 | p=Process(target=self.get_page) 74 | p.start() 75 | 76 | def loop_all_get(self,loop_times): 77 | for cookie in self.cookies: 78 | self.set_headers(cookie) 79 | p=Process(target=self.pool_loop,args=(loop_times,self.get_page)) 80 | p.start() 81 | 82 | 83 | class PostCoupon(MyInfo): 84 | def set_passwords(self,passwords_url): 85 | self.passwords=self.get_userdata(passwords_url) 86 | 87 | def set_password(self,n): 88 | self.password=self.passwords[n-1] 89 | 90 | def set_itemId(self,itemId): 91 | self.itemId=itemId 92 | 93 | def get_token(self): 94 | s=requests.session() 95 | r=s.get('http://vip.jd.com/bean/{}.html'.format(self.itemId)) 96 | cer=re.compile('pageConfig.token="(.*)"') 97 | self.token=cer.findall(r.text)[0] 98 | print('token='+self.token) 99 | 100 | def post_page(self): 101 | s=requests.session() 102 | s.headers=self.headers 103 | self.data='itemId={}&password={}&token={}'.format(self.itemId,self.password,self.token) 104 | try: 105 | r=s.post('http://vip.jd.com/bean/exchangeCoupon.html',data=self.data,timeout=10) 106 | if '提交错误' in r.text: 107 | self.get_token() 108 | return self.post_page() 109 | except (requests.ConnectTimeout,requests.ReadTimeout): 110 | print('超时重试中,若依然如此请检查网络') 111 | except: 112 | pass 113 | else: 114 | print(r.text) 115 | 116 | def one_post(self,n): 117 | self.set_headers(self.cookies[n-1]) 118 | self.headers['Content-Type']='application/x-www-form-urlencoded' 119 | self.set_password(n) 120 | self.post_page() 121 | 122 | def loop_one_post(self,n,loop_times): 123 | self.set_headers(self.cookies[n-1]) 124 | self.headers['Content-Type']='application/x-www-form-urlencoded' 125 | self.set_password(n) 126 | self.pool_loop(loop_times,self.post_page) 127 | 128 | def all_post(self): 129 | for i in range(len(self.passwords)): 130 | self.password=self.passwords[i] 131 | self.set_headers(self.cookies[i]) 132 | self.headers['Content-Type']='application/x-www-form-urlencoded' 133 | p=Process(target=self.post_page) 134 | p.start() 135 | 136 | def loop_all_post(self,loop_times): 137 | for i in range(len(self.passwords)): 138 | self.password=self.passwords[i] 139 | self.set_headers(self.cookies[i]) 140 | self.headers['Content-Type']='application/x-www-form-urlencoded' 141 | p=Process(target=self.pool_loop,args=(loop_times,self.post_page)) 142 | p.start() 143 | 144 | 145 | class Coupon(timing.Time,GetCoupon,PostCoupon): 146 | def __init__(self): 147 | MyInfo.__init__(self) 148 | print('*===============请选择操作模式================*') 149 | print('* (1)单个用户 *') 150 | print('* (2)所有用户 *') 151 | print('* (3)单个用户 and 循环 *') 152 | print('* (4)所有用户 and 循环 *') 153 | print('* (5)单个用户 and 定时 *') 154 | print('* (6)所有用户 and 定时 *') 155 | print('* (7)单个用户 and 定时 and 循环 *') 156 | print('* (8)所有用户 and 定时 and 循环 *') 157 | print('*===========================================*') 158 | 159 | def run(self): 160 | name=input('请选择(1)get,(2)post(0)退出:').strip() 161 | if name=='1': 162 | name='get' 163 | m=int(input('请选择第m个url:')) 164 | self.set_url(m) 165 | elif name=='2': 166 | name='post' 167 | itemId=input('请输入itemId(参考http://vip.jd.com/bean/(itemId).html):') 168 | self.set_itemId(itemId) 169 | self.get_token() 170 | self.set_passwords('C:\\Users\肥皂\Desktop\\password.txt') 171 | elif name=='0': 172 | print('退出成功') 173 | exit() 174 | else: 175 | print('输入错误,请重新输入!') 176 | return self.run() 177 | y=int(input('请选择模式(y):')) 178 | if y==1: 179 | n=int(input('请选择第n个用户操作:')) 180 | eval('self.one_{}'.format(name))(n) 181 | elif y==2: 182 | eval('self.all_{}'.format(name))() 183 | elif y==3: 184 | n=int(input('请选择第n个用户操作:')) 185 | loop_times=int(input('请输入循环次数:')) 186 | eval('self.loop_one_{}'.format(name))(n,loop_times) 187 | elif y==4: 188 | loop_times=int(input('请输入循环次数:')) 189 | eval('self.loop_all_{}'.format(name))(loop_times) 190 | elif y==5: 191 | n=int(input('请选择第n个用户操作:')) 192 | self.timer() 193 | eval('self.one_{}'.format(name))(n) 194 | elif y==6: 195 | self.timer() 196 | eval('self.all_{}'.format(name))() 197 | elif y==7: 198 | n=int(input('请选择第n个用户操作:')) 199 | loop_times=int(input('请输入循环次数:')) 200 | self.timer() 201 | eval('self.loop_one_{}'.format(name))(n,loop_times) 202 | elif y==8: 203 | loop_times=int(input('请输入循环次数:')) 204 | self.timer() 205 | eval('self.loop_all_{}'.format(name))(loop_times) 206 | else: 207 | print('模式输入错误,请重新输入!') 208 | return self.run() 209 | time.sleep(5) 210 | 211 | -------------------------------------------------------------------------------- /jd_review.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | import mysql.connector 4 | 5 | class reviewer(object): 6 | def __init__(self): 7 | self.flag='0' 8 | self.score_dict={1:'negative',2:'neutral',3:'positive'} 9 | 10 | def connect_mysql(self): 11 | self.conn=mysql.connector.connect(user='root',password='') 12 | self.cursor=self.conn.cursor() 13 | self.cursor.execute('create database if not exists jd') 14 | self.conn.connect(database='jd') 15 | self.create_table() 16 | 17 | def create_table(self): 18 | try: 19 | self.cursor.execute('create table %s (id varchar(200) primary key,nickname varchar(20),content varchar(500),score char(1),classify varchar(20))' %('goods_'+self.product_id)) 20 | except mysql.connector.Error as e: 21 | self.flag=input('您已爬取过该商品的评价,您确定要重新爬取吗?y/n:') 22 | if self.flag=='y': 23 | self.cursor.execute('drop table %s' %('goods_'+self.product_id)) 24 | return self.create_table() 25 | elif self.flag=='n': 26 | return 27 | else: 28 | print('输入错误!') 29 | return self.create_table() 30 | except Exception as e: 31 | print(e) 32 | exit(-1) 33 | 34 | def find_review(self,score,max_page=20): 35 | page=0 36 | page_data='' 37 | while True: 38 | url='https://sclub.jd.com/comment/productPageComments.action?productId={}&score={}&sortType=3&page={}&pageSize=10'.format(self.product_id,score,page) 39 | r=requests.get(url) 40 | if page_data==r.text: 41 | return page 42 | page_data=r.text 43 | data=json.loads(page_data) 44 | if len(data['comments']) and page(.*)',flags=0) 23 | self.skuName=cer.findall(r) 24 | if not self.skuName: 25 | print('您输入的商品ID有误!') 26 | return self.set_skuId() 27 | else: 28 | print(self.skuName[0]) 29 | 30 | def get_price(self): 31 | for key,value in self.price_dict.items(): 32 | r=json.loads(requests.get(value.format(self.skuId)).text)[0]['p'] 33 | print(key,r) 34 | 35 | 36 | def get_stock(self): 37 | provinceName=input('请输入要查询的省份(如湖南):') 38 | if provinceName in self.province_dict.keys(): 39 | r=json.loads(requests.get('https://c0.3.cn/stock?skuId={skuId}&cat=1316,1385,1408&area={province}_2805_2855'.format(skuId=self.skuId,province=str(self.province_dict[provinceName]))+'&extraParam={%22originid%22:%221%22}').text) 40 | print(r['stock']['area']['provinceName'],':',r['stock']['StockStateName']) 41 | if r['stock']['StockStateName']=='无货': 42 | flag=input('商品暂时无货,是否循环监控?y/n:') 43 | if flag=='y': 44 | while True: 45 | r=json.loads(requests.get('https://c0.3.cn/stock?skuId={skuId}&cat=1316,1385,1408&area={province}_2805_2855'.format(skuId=self.skuId,province=str(self.province_dict[provinceName]))+'&extraParam={%22originid%22:%221%22}').text) 46 | print(r['stock']['area']['provinceName'],':',r['stock']['StockStateName']) 47 | if r['stock']['StockStateName']=='现货': 48 | for i in range(4): 49 | winsound.Beep(800,250) 50 | print(r['stock']['area']['provinceName'],':',r['stock']['StockStateName']) 51 | time.sleep(1) 52 | time.sleep(0.3) 53 | winsound.Beep(1600,500) 54 | break 55 | time.sleep(5) 56 | else: 57 | print('您的输入有误,请重新输入!') 58 | return self.get_stock() -------------------------------------------------------------------------------- /timing.py: -------------------------------------------------------------------------------- 1 | import ntplib,time 2 | 3 | class Time(object): 4 | def get_ntptime(self): 5 | client=ntplib.NTPClient() 6 | try: 7 | response=client.request('202.108.6.95',timeout=1) 8 | except ntplib.NTPException: 9 | print('校正超时,重新校正...') 10 | return self.get_ntptime() 11 | else: 12 | my_timestamp=response.tx_time 13 | print('校正时间:',my_timestamp) 14 | return my_timestamp 15 | 16 | def timer(self): 17 | print('当前时间:',time.strftime('%Y-%m-%d %H;%M:%S',time.localtime(self.get_ntptime()))) 18 | target_time=input('请输入目标时间(如00:00:00):') 19 | date=time.strftime('%Y-%m-%d',time.localtime(time.time())) 20 | target_stamp=time.mktime(time.strptime((date+' '+target_time),'%Y-%m-%d %H:%M:%S')) 21 | print('目标时间:',time.strftime('%Y-%m-%d %H;%M:%S',time.localtime(target_stamp))) 22 | print('定时等待中...') 23 | my_timestamp=self.get_ntptime() 24 | i=0 25 | while my_timestamp