extract_and_save.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. from playwright.sync_api import sync_playwright
  2. import sqlite3
  3. import smtplib
  4. from email.mime.text import MIMEText
  5. from email.header import Header
  6. import random
  7. import logging
  8. import time
  9. import requests as req
  10. import re
  11. import json
  12. logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(message)s')
  13. logger = logging.getLogger(__name__)
  14. def run(session='', sender_email='', receiver_email='', smtp_proxy='', smtp_account='', smtp_password='', email_alias='', error_count=3):
  15. # 初始化数据
  16. count = 0
  17. dx_my_headers = {
  18. "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
  19. "X-Requested-With": "XMLHttpRequest"
  20. }
  21. try:
  22. # get 请求
  23. dx_my_headers.update({
  24. 'Cookie': f'sessions={session}'
  25. })
  26. api_url="https://c.dun.163.com/api/v3/get?referer=https%3A%2F%2Fbuff.163.com%2Fgoods%2F921509&zoneId=CN31&dt=8gRTZRf8UUxEA1EREFPCNl0v%2BDhw0mZg&acToken=9ca17ae2e6ffcda170e2e6eeaecf6088eae189c63baeb88fb7d14a938f8f87db43af92f783cf52f7a8bab6f02af0feaec3b92af4afb698e15491bdb7d2eb4f878a9ab3d84e8d99add3e55295adf984d94a9288ee9e&id=176df3efe81a4945978a3dc4ce277139&fp=d1%5CgemagKNZrEyaLbQJldfuJj39Z963luTbM%2BUHtRgoypfCmVHuL2aiSo84O2mS63vHmfLXXrsTstfCUWX1y2W4Pj22UXQwe7zo8w%2FQZ805%2FWiUzxm%5C%5CANYurvHNf%2BDU%2Fkh9Ka2031QT6%2BczlNCUHJlERqoDKZHtpjwqOPjcpiIC7DNK%3A1740976364913&https=true&type=undefined&version=2.27.2&dpr=2&dev=1&cb=65e.pcSwFeSYbuuunMPYWtbkxsAhWWAkAPWzHEMpZ.aCjclRQDjRJA3A.r2mBLsH2uCaiubbhQaXbkux2KMiENC.o%2FY7&ipv6=false&runEnv=10&group=&scene=&lang=zh-CN&sdkVersion=undefined&iv=4&width=320&audio=false&sizeType=10&smsVersion=v3&token=&callback=__JSONP_p2z3mwq_0"
  27. api2_res = req.get(api_url, headers=dx_my_headers)
  28. # 获取api2_res的body内容
  29. logger.info(f'接口返回:{api2_res.text}')
  30. # 使用正则表达式提取 JSON 部分
  31. json_string = re.search(r'\((.*)\)', api2_res.text).group(1)
  32. logger.info(json_string)
  33. # 将 JSON 字符串转换为 Python 字典
  34. data = json.loads(json_string)
  35. error_value = data['error']
  36. # 成功的话
  37. if error_value == '0':
  38. msg_content = data['data']['front']
  39. msg_content_list = msg_content.split(',')
  40. edit_content = msg_content_list[0]
  41. send_content_short = msg_content_list[1]
  42. logger.info(f'短信内容: {edit_content},短信发送到: {send_content_short}')
  43. # 发件人邮箱账号
  44. sender = sender_email
  45. # 收件人邮箱账号,可以是多个
  46. receivers = receiver_email
  47. # 邮件正文内容
  48. message = MIMEText(f'编辑短信{edit_content}', 'plain', 'utf-8')
  49. # 邮件主题
  50. message['Subject'] = Header(f'{email_alias}编辑短信{edit_content}', 'utf-8')
  51. # 发件人和收件人
  52. message['From'] = sender_email
  53. message['To'] = receiver_email
  54. try:
  55. # 连接到SMTP服务器,使用SSL连接(端口465)或TLS连接(端口587)
  56. smtpObj = smtplib.SMTP_SSL(smtp_proxy, 465) # 使用SSL连接示例
  57. # smtpObj = smtplib.SMTP("smtp.126.com", 587) # 使用TLS连接示例,需要先调用smtpObj.starttls()
  58. # smtpObj.starttls() # 如果使用TLS连接,取消注释这行并注释上一行中的SSL连接部分
  59. # 登录SMTP服务器
  60. smtpObj.login(sender, smtp_password) # 注意:出于安全考虑,建议使用应用专用密码而非你的邮箱密码
  61. # 发送邮件
  62. smtpObj.sendmail(sender, receivers, message.as_string())
  63. logger.info("邮件发送成功")
  64. except smtplib.SMTPException as e:
  65. logger.info("Error: 无法发送邮件", e)
  66. finally:
  67. smtpObj.quit()
  68. # Step 5: Save to SQLite database
  69. conn = sqlite3.connect('settings.db')
  70. cursor = conn.cursor()
  71. cursor.execute('''CREATE TABLE IF NOT EXISTS sms_codes (edit_content TEXT, send_content_short TEXT)''')
  72. cursor.execute('''INSERT INTO sms_codes (edit_content, send_content_short) VALUES (?, ?)''', (edit_content, send_content_short))
  73. conn.commit()
  74. # 判断sms_codes表中的数据量是否大于3
  75. cursor.execute('''SELECT COUNT(*) FROM sms_codes''')
  76. # 获取执行结果
  77. count = cursor.fetchone()[0]
  78. conn.close()
  79. logger.info("暂停180秒,给短信验证预留时间")
  80. time.sleep(180)
  81. else:
  82. # 失败的话
  83. logger.info("清空表sms_codes")
  84. conn = sqlite3.connect('settings.db')
  85. cursor = conn.cursor()
  86. cursor.execute('''CREATE TABLE IF NOT EXISTS sms_codes (edit_content TEXT, send_content_short TEXT)''')
  87. cursor.execute('delete from sms_codes')
  88. conn.commit()
  89. conn.close()
  90. # logger.info("未监测到短信数据")
  91. return 'success'
  92. # with sync_playwright() as playwright:
  93. # browser = playwright.chromium.launch(headless=False)
  94. # context = browser.new_context()
  95. # page = context.new_page()
  96. #
  97. # # 添加session cookie
  98. # cookies = [
  99. # {
  100. # 'name': 'session',
  101. # 'value': session, # 替换为实际的session值
  102. # 'domain': 'buff.163.com',
  103. # 'path': '/',
  104. # }
  105. # ]
  106. # context.add_cookies(cookies)
  107. #
  108. # # 商品池子
  109. # # goods_info = [776831, 911801, 42234, 33887, 781577, 968110, 968048, 968047, 968046, 968045, 968044, 968043, 968042, 968041, 968040, 968039, 968038, 968037, 968036, 968035, 968034, 968033, 968032, 968031, 968030, 968029, 968028, 968027, 968026, 968025, 968024, 968023, 968022, 968021, 968020, 968019, 968018, ]
  110. # goods_info = [968020]
  111. # # 从goods_info随机获取一个值
  112. # random_number = random.choice(goods_info)
  113. #
  114. # # Step 1: Visit the initial URL
  115. # page.goto(f"https://buff.163.com/goods/{random_number}?from=market#tab=selling")
  116. # # Step 2: Click the "无法扫描二维码" button
  117. # # 等待page加载完毕
  118. # page.wait_for_load_state('networkidle')
  119. # # logger.info(f"点击无法扫描二维码按钮-是否存在(0:不存在,1:存在): {page.locator('span.yidun_smsbox-text--manual').count()}")
  120. # if page.locator('span.yidun_smsbox-text--manual').count() <= 0 :
  121. # # logger.info("清空表sms_codes")
  122. # conn = sqlite3.connect('settings.db')
  123. # cursor = conn.cursor()
  124. # cursor.execute('''CREATE TABLE IF NOT EXISTS sms_codes (edit_content TEXT, send_content_short TEXT)''')
  125. # cursor.execute('delete from sms_codes')
  126. # conn.commit()
  127. # conn.close()
  128. # # Close the browser
  129. # context.close()
  130. # browser.close()
  131. # # logger.info("未监测到短信数据")
  132. # return False
  133. # page.click('span.yidun_smsbox-text--manual')
  134. #
  135. # # Step 3: Wait for navigation to the new page
  136. # page.wait_for_load_state('networkidle')
  137. # # Step 4: Extract the required content
  138. # edit_content = page.inner_text('span.yidun_smsbox-manual--edit-content')
  139. # send_content_short = page.inner_text('span.yidun_smsbox-manual--send-content__short')
  140. # logger.info(f'短信发送到: {send_content_short},短信内容: {edit_content}')
  141. # # 发件人邮箱账号
  142. # sender = sender_email
  143. # # 收件人邮箱账号,可以是多个
  144. # receivers = receiver_email
  145. # # 邮件正文内容
  146. # message = MIMEText(f'编辑短信{edit_content}', 'plain', 'utf-8')
  147. # # 邮件主题
  148. # message['Subject'] = Header(f'{email_alias}编辑短信{edit_content}', 'utf-8')
  149. # # 发件人和收件人
  150. # message['From'] = sender_email
  151. # message['To'] = receiver_email
  152. # try:
  153. # # 连接到SMTP服务器,使用SSL连接(端口465)或TLS连接(端口587)
  154. # smtpObj = smtplib.SMTP_SSL(smtp_proxy, 465) # 使用SSL连接示例
  155. # # smtpObj = smtplib.SMTP("smtp.126.com", 587) # 使用TLS连接示例,需要先调用smtpObj.starttls()
  156. # # smtpObj.starttls() # 如果使用TLS连接,取消注释这行并注释上一行中的SSL连接部分
  157. # # 登录SMTP服务器
  158. # smtpObj.login(sender, smtp_password) # 注意:出于安全考虑,建议使用应用专用密码而非你的邮箱密码
  159. # # 发送邮件
  160. # smtpObj.sendmail(sender, receivers, message.as_string())
  161. # logger.info("邮件发送成功")
  162. # except smtplib.SMTPException as e:
  163. # logger.info("Error: 无法发送邮件", e)
  164. # finally:
  165. # smtpObj.quit()
  166. #
  167. # # Step 5: Save to SQLite database
  168. # conn = sqlite3.connect('settings.db')
  169. # cursor = conn.cursor()
  170. # cursor.execute('''CREATE TABLE IF NOT EXISTS sms_codes (edit_content TEXT, send_content_short TEXT)''')
  171. # cursor.execute('''INSERT INTO sms_codes (edit_content, send_content_short) VALUES (?, ?)''', (edit_content, send_content_short))
  172. # conn.commit()
  173. # # 判断sms_codes表中的数据量是否大于3
  174. # cursor.execute('''SELECT COUNT(*) FROM sms_codes''')
  175. # # 获取执行结果
  176. # count = cursor.fetchone()[0]
  177. # conn.close()
  178. #
  179. # wait_times = 0
  180. # # 监测span.yidun_smsbox-manual--edit-content元素,如果元素消失了才能关闭浏览器,超过了3分钟自动关闭
  181. # while page.locator('span.yidun_smsbox-manual--edit-content').count() > 0 and wait_times < 180:
  182. # logger.info(f"等待系统验证通过中........,已等待{wait_times}秒")
  183. # wait_times += 1
  184. # time.sleep(1)
  185. # if page.locator('span.yidun_smsbox-manual--edit-content').count() <= 0:
  186. # logger.info(f"系统验证通过")
  187. # if wait_times >= 180:
  188. # logger.info(f"等待系统验证通过超时")
  189. #
  190. # # Close the browser
  191. # context.close()
  192. # browser.close()
  193. # 如果count大于等于三,则返回'stop'
  194. if count >= int(error_count):
  195. logger.info(f'达到异常关闭条件,连续异常次数:{count},指标为:{error_count},返回True,结束程序')
  196. return 'stop'
  197. else:
  198. logger.info(f'未达到异常关闭条件,,连续异常次数:{count},指标为:{error_count} 返回False')
  199. return 'error not stop'
  200. except Exception as e:
  201. logger.info(f"未监测到短信数据: {e}")
  202. return 'error not stop'
  203. finally:
  204. pass
  205. if __name__ == "__main__":
  206. result = run(
  207. session='session',
  208. sender_email='sender_email',
  209. receiver_email='receiver_email',
  210. smtp_proxy='smtp_proxy',
  211. smtp_account='smtp_account',
  212. smtp_password='smtp_password',
  213. email_alias='email_alias',
  214. error_count='3'
  215. )
  216. logger.info(result)