From 6396b1f8d00c45a1915f7980217dce2df210df43 Mon Sep 17 00:00:00 2001 From: Germey Date: Sun, 30 Apr 2017 20:49:18 +0800 Subject: [PATCH] version 1.0 --- .gitignore | 3 + README.md | 3 + cookiespool/__init__.py | 0 cookiespool/api.py | 59 +++++++++++ cookiespool/config.py | 52 ++++++++++ cookiespool/db.py | 210 +++++++++++++++++++++++++++++++++++++++ cookiespool/error.py | 48 +++++++++ cookiespool/generator.py | 169 +++++++++++++++++++++++++++++++ cookiespool/importer.py | 24 +++++ cookiespool/scheduler.py | 56 +++++++++++ cookiespool/tester.py | 61 ++++++++++++ cookiespool/verify.py | 137 +++++++++++++++++++++++++ run.py | 8 ++ tests/login.py | 17 ++++ 14 files changed, 847 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 cookiespool/__init__.py create mode 100644 cookiespool/api.py create mode 100644 cookiespool/config.py create mode 100644 cookiespool/db.py create mode 100644 cookiespool/error.py create mode 100644 cookiespool/generator.py create mode 100644 cookiespool/importer.py create mode 100644 cookiespool/scheduler.py create mode 100644 cookiespool/tester.py create mode 100644 cookiespool/verify.py create mode 100644 run.py create mode 100644 tests/login.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ecf5669 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.idea +*.pyc +ghostdriver.log \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..15ba445 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# CookiesPool + +CookiesPool Based on Redis and Flask \ No newline at end of file diff --git a/cookiespool/__init__.py b/cookiespool/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cookiespool/api.py b/cookiespool/api.py new file mode 100644 index 0000000..736c31c --- /dev/null +++ b/cookiespool/api.py @@ -0,0 +1,59 @@ +from flask import Flask, g +from cookiespool.config import * +from cookiespool.db import CookiesRedisClient, AccountRedisClient + +__all__ = ['app'] + +app = Flask(__name__) + + +@app.route('/') +def index(): + return '

Welcome to Cookie Pool System

' + + +def get_conn(): + """ + 获取 + :return: + """ + for name in GENERATOR_MAP: + print(name) + if not hasattr(g, name): + setattr(g, name + '_cookies', eval('CookiesRedisClient' + '(name="' + name + '")')) + setattr(g, name + '_account', eval('AccountRedisClient' + '(name="' + name + '")')) + return g + + +@app.route('//random') +def random(name): + """ + 获取随机的Cookie, 访问地址如 /weibo/random + :return: 随机Cookie + """ + g = get_conn() + cookies = getattr(g, name + '_cookies').random() + return cookies + +@app.route('//add//') +def add(name, username, password): + """ + 添加用户, 访问地址如 /weibo/add/user/password + """ + g = get_conn() + result = getattr(g, name + '_account').set(username, password) + return result + + +@app.route('//count') +def count(name): + """ + 获取Cookies总数 + """ + g = get_conn() + count = getattr(g, name + '_cookies').count() + return str(int) if isinstance(count, int) else count + + +if __name__ == '__main__': + app.run(host='0.0.0.0') diff --git a/cookiespool/config.py b/cookiespool/config.py new file mode 100644 index 0000000..06d703a --- /dev/null +++ b/cookiespool/config.py @@ -0,0 +1,52 @@ +# Redis数据库地址 +REDIS_HOST = 'localhost' + +REDIS_PORT = 6379 + +REDIS_PASSWORD = 'foobared' + +REDIS_DOMAIN = '*' + +REDIS_NAME = '*' + +# 云打码相关配置到yundama.com申请注册 +YUNDAMA_USERNAME = 'Germey' + +YUNDAMA_PASSWORD = '940629cqc' + +YUNDAMA_APP_ID = '3372' + +YUNDAMA_APP_KEY = '1b586a30bfda5c7fa71c881075ba49d0' + +YUNDAMA_API_URL = 'http://api.yundama.com/api.php' + +YUNDAMA_MAX_RETRY = 20 + +# 产生器默认使用的浏览器 +DEFAULT_BROWSER = 'PhantomJS' + +# 产生器类 +GENERATOR_MAP = { + 'weibo': 'WeiboCookiesGenerator' +} + +# 测试类 +TESTER_MAP = { + 'weibo': 'WeiboValidTester' +} + +# 产生器和验证器循环周期 +CYCLE = 120 + +# API地址和端口 +API_HOST = '127.0.0.1' + +API_PORT = 5000 + +# 进程开关 +# 产生器 +GENERATOR_PROCESS = True +# 验证器 +VALID_PROCESS = False +# API +API_PROCESS = True diff --git a/cookiespool/db.py b/cookiespool/db.py new file mode 100644 index 0000000..9121122 --- /dev/null +++ b/cookiespool/db.py @@ -0,0 +1,210 @@ +import random +import redis +from cookiespool.config import * +from cookiespool.error import * + + +class RedisClient(object): + def __init__(self, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD): + """ + 初始化Redis连接 + :param host: 地址 + :param port: 端口 + :param password: 密码 + """ + if password: + self._db = redis.Redis(host=host, port=port, password=password) + else: + self._db = redis.Redis(host=host, port=port) + self.domain = REDIS_DOMAIN + self.name = REDIS_NAME + + def _key(self, key): + """ + 得到格式化的key + :param key: 最后一个参数key + :return: + """ + return "{domain}:{name}:{key}".format(domain=self.domain, name=self.name, key=key) + + def set(self, key, value): + """ + 设置键值对 + :param key: + :param value: + :return: + """ + raise NotImplementedError + + def get(self, key): + """ + 根据键名获取键值 + :param key: + :return: + """ + raise NotImplementedError + + def delete(self, key): + """ + 根据键名删除键值对 + :param key: + :return: + """ + raise NotImplementedError + + def keys(self): + """ + 得到所有的键名 + :return: + """ + return self._db.keys('{domain}:{name}:*'.format(domain=self.domain, name=self.name)) + + def flush(self): + """ + 清空数据库, 慎用 + :return: + """ + self._db.flushall() + + +class CookiesRedisClient(RedisClient): + def __init__(self, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, domain='cookies', name='default'): + """ + 管理Cookies的对象 + :param host: 地址 + :param port: 端口 + :param password: 密码 + :param domain: 域, 如cookies, account等 + :param name: 名称, 一般为站点名, 如 weibo, 默认 default + """ + RedisClient.__init__(self, host, port, password) + self.domain = domain + self.name = name + + def set(self, key, value): + try: + self._db.set(self._key(key), value) + except: + raise SetCookieError + + def get(self, key): + try: + return self._db.get(self._key(key)).decode('utf-8') + except: + return None + + def delete(self, key): + try: + print('Delete', key) + return self._db.delete(self._key(key)) + except: + raise DeleteCookieError + + def random(self): + """ + 随机得到一Cookies + :return: + """ + try: + keys = self.keys() + return self._db.get(random.choice(keys)) + except: + raise GetRandomCookieError + + def all(self): + """ + 获取所有账户, 以字典形式返回 + :return: + """ + try: + for key in self._db.keys('{domain}:{name}:*'.format(domain=self.domain, name=self.name)): + group = key.decode('utf-8').split(':') + if len(group) == 3: + username = group[2] + yield { + 'username': username, + 'cookies': self.get(username) + } + except Exception as e: + print(e.args) + raise GetAllCookieError + + def count(self): + """ + 获取当前Cookies数目 + :return: 数目 + """ + return len(self.keys()) + + + +class AccountRedisClient(RedisClient): + def __init__(self, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, domain='account', name='default'): + RedisClient.__init__(self, host, port, password) + self.domain = domain + self.name = name + + def set(self, key, value): + try: + return self._db.set(self._key(key), value) + except: + raise SetAccountError + + def get(self, key): + try: + return self._db.get(self._key(key)).decode('utf-8') + except: + raise GetAccountError + + def all(self): + """ + 获取所有账户, 以字典形式返回 + :return: + """ + try: + for key in self._db.keys('{domain}:{name}:*'.format(domain=self.domain, name=self.name)): + group = key.decode('utf-8').split(':') + if len(group) == 3: + username = group[2] + yield { + 'username': username, + 'password': self.get(username) + } + except Exception as e: + print(e.args) + raise GetAllAccountError + + def delete(self, key): + """ + 通过用户名删除用户 + :param key: + :return: + """ + try: + return self._db.delete(self._key(key)) + except: + raise DeleteAccountError + + +if __name__ == '__main__': + """ + conn = CookiesRedisClient() + conn.set('name', 'Mike') + conn.set('name2', 'Bob') + conn.set('name3', 'Amy') + print(conn.get('name')) + conn.delete('name') + print(conn.keys()) + print(conn.random()) + """ + # 测试 + conn = AccountRedisClient(name='weibo') + conn.set('14760253606', 'gmidy8470') + conn.set('14760253607', 'uoyuic8427') + conn.set('18459749258', 'rktfye8937') + conn.set('18459748505', 'astvar3647') + print(conn.get('18459748505')) + print(conn.keys()) + accounts = conn.all() + for account in accounts: + print(account) diff --git a/cookiespool/error.py b/cookiespool/error.py new file mode 100644 index 0000000..feed029 --- /dev/null +++ b/cookiespool/error.py @@ -0,0 +1,48 @@ +class CookiePoolError(Exception): + def __str__(self): + return repr('Cookie Pool Error') + + +class SetCookieError(CookiePoolError): + def __str__(self): + return repr('Set Cookie Error') + + +class GetCookieError(CookiePoolError): + def __str__(self): + return repr('Get Cookie Error') + + +class DeleteCookieError(CookiePoolError): + def __str__(self): + return repr('Delete Cookie Error') + + +class GetRandomCookieError(CookiePoolError): + def __str__(self): + return repr('Get Random Cookie Error') + + +class GetAllCookieError(CookiePoolError): + def __str__(self): + return repr('Get All Cookie Error') + + +class SetAccountError(CookiePoolError): + def __str__(self): + return repr('Set Account Error') + + +class DeleteAccountError(CookiePoolError): + def __str__(self): + return repr('Delete Account Error') + + +class GetAccountError(CookiePoolError): + def __str__(self): + return repr('Get Account Error') + + +class GetAllAccountError(CookiePoolError): + def __str__(self): + return repr('Get All Account Error') diff --git a/cookiespool/generator.py b/cookiespool/generator.py new file mode 100644 index 0000000..b89cf92 --- /dev/null +++ b/cookiespool/generator.py @@ -0,0 +1,169 @@ +import json +import requests +import time +from selenium import webdriver +from selenium.webdriver import DesiredCapabilities +from selenium.common.exceptions import WebDriverException, TimeoutException +from selenium.webdriver.common.by import By +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from cookiespool.db import CookiesRedisClient, AccountRedisClient +from cookiespool.verify import Yundama +from cookiespool.config import * +from requests.exceptions import ConnectionError + + +class CookiesGenerator(object): + def __init__(self, name='default', browser_type=DEFAULT_BROWSER): + """ + 父类, 初始化一些对象 + :param name: 名称 + :param browser: 浏览器, 若不使用浏览器则可设置为 None + """ + self.name = name + self.cookies_db = CookiesRedisClient(name=self.name) + self.account_db = AccountRedisClient(name=self.name) + self.browser_type = browser_type + + def _init_browser(self, browser_type): + """ + 通过browser参数初始化全局浏览器供模拟登录使用 + :param browser: 浏览器 PhantomJS/ Chrome + :return: + """ + if browser_type == 'PhantomJS': + caps = DesiredCapabilities.PHANTOMJS + caps[ + "phantomjs.page.settings.userAgent"] = "Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1" + self.browser = webdriver.PhantomJS(desired_capabilities=caps) + elif browser_type == 'Chrome': + self.browser = webdriver.Chrome() + + def new_cookies(self, username, password): + raise NotImplementedError + + def set_cookies(self, account): + """ + 根据账户设置新的Cookies + :param account: + :return: + """ + results = self.new_cookies(account.get('username'), account.get('password')) + if results: + username, cookies = results + print('Saving Cookies to Redis', username, cookies) + self.cookies_db.set(username, cookies) + + + def run(self): + """ + 运行, 得到所有账户, 然后顺次模拟登录 + :return: + """ + accounts = self.account_db.all() + cookies = self.cookies_db.all() + # Account 中对应的用户 + accounts = list(accounts) + # Cookies中对应的用户 + valid_users = [cookie.get('username') for cookie in cookies] + print('Getting', len(accounts), 'accounts from Redis') + if len(accounts): + self._init_browser(browser_type=self.browser_type) + for account in accounts: + if not account.get('username') in valid_users: + print('Getting Cookies of ', self.name, account.get('username'), account.get('password')) + self.set_cookies(account) + print('Generator Run Finished') + + def close(self): + try: + print('Closing Browser') + self.browser.close() + del self.browser + except TypeError: + print('Browser not opened') + + +class WeiboCookiesGenerator(CookiesGenerator): + def __init__(self, name='weibo', browser_type=DEFAULT_BROWSER): + """ + 初始化操作, 微博需要声明一个云打码引用 + :param name: 名称微博 + :param browser: 使用的浏览器 + """ + CookiesGenerator.__init__(self, name, browser_type) + self.name = name + self.ydm = Yundama(YUNDAMA_USERNAME, YUNDAMA_PASSWORD, YUNDAMA_APP_ID, YUNDAMA_APP_KEY) + + def _success(self, username): + wait = WebDriverWait(self.browser, 5) + success = wait.until(EC.visibility_of_element_located((By.CLASS_NAME, 'me_portrait_w'))) + if success: + print('登录成功') + self.browser.get('http://weibo.cn/') + + if "我的首页" in self.browser.title: + print(self.browser.get_cookies()) + cookies = {} + for cookie in self.browser.get_cookies(): + cookies[cookie["name"]] = cookie["value"] + print(cookies) + print('成功获取到Cookies') + return (username, json.dumps(cookies)) + + def new_cookies(self, username, password): + """ + 生成Cookies + :param username: 用户名 + :param password: 密码 + :return: 用户名和Cookies + """ + print('Generating Cookies of', username) + self.browser.delete_all_cookies() + self.browser.get('http://my.sina.com.cn/profile/unlogin') + wait = WebDriverWait(self.browser, 20) + + try: + login = wait.until(EC.visibility_of_element_located((By.ID, 'hd_login'))) + login.click() + user = wait.until( + EC.visibility_of_element_located((By.CSS_SELECTOR, '.loginformlist input[name="loginname"]'))) + user.send_keys(username) + psd = wait.until( + EC.visibility_of_element_located((By.CSS_SELECTOR, '.loginformlist input[name="password"]'))) + psd.send_keys(password) + submit = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '.login_btn'))) + submit.click() + try: + result = self._success(username) + if result: + return result + except TimeoutException: + print('出现验证码,开始识别验证码') + yzm = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '.loginform_yzm .yzm'))) + url = yzm.get_attribute('src') + cookies = self.browser.get_cookies() + cookies_dict = {} + for cookie in cookies: + cookies_dict[cookie.get('name')] = cookie.get('value') + response = requests.get(url, cookies=cookies_dict) + result = self.ydm.identify(stream=response.content) + if not result: + print('验证码识别失败, 跳过识别') + return + door = wait.until( + EC.visibility_of_element_located((By.CSS_SELECTOR, '.loginform_yzm input[name="door"]'))) + door.send_keys(result) + submit.click() + result = self._success(username) + if result: + return result + except WebDriverException as e: + print(e.args) + + +if __name__ == '__main__': + generator = WeiboCookiesGenerator() + generator._init_browser('Chrome') + generator.new_cookies('15197170054', 'gmwkms222') diff --git a/cookiespool/importer.py b/cookiespool/importer.py new file mode 100644 index 0000000..519ba16 --- /dev/null +++ b/cookiespool/importer.py @@ -0,0 +1,24 @@ +import requests + +from cookiespool.db import AccountRedisClient + +conn = AccountRedisClient(name='weibo') + +def set(account, sep='----'): + username, password = account.split(sep) + result = conn.set(username, password) + print('账号', username, '密码', password) + print('录入成功' if result else '录入失败') + + +def scan(): + print('请输入账号密码组, 输入exit退出读入') + while True: + account = input() + if account == 'exit': + break + set(account) + + +if __name__ == '__main__': + scan() \ No newline at end of file diff --git a/cookiespool/scheduler.py b/cookiespool/scheduler.py new file mode 100644 index 0000000..e2feca6 --- /dev/null +++ b/cookiespool/scheduler.py @@ -0,0 +1,56 @@ +import time +from multiprocessing import Process +from cookiespool.tester import * +from cookiespool.config import * +from cookiespool.api import app +import os +import signal + + +class Scheduler(object): + @staticmethod + def valid_cookie(cycle=CYCLE): + while True: + print('Checking Cookies') + try: + for name, cls in TESTER_MAP.items(): + tester = eval(cls + '()') + tester.run() + print('Tester Finished') + del tester + time.sleep(cycle) + except Exception as e: + print(e.args) + + @staticmethod + def generate_cookie(cycle=CYCLE): + while True: + print('Generating Cookies') + try: + for name, cls in GENERATOR_MAP.items(): + generator = eval(cls + '()') + generator.run() + print('Generator Finished') + generator.close() + print('Deleted Generator') + time.sleep(cycle) + except Exception as e: + print(e.args) + + @staticmethod + def api(): + app.run(host=API_HOST, port=API_PORT) + + def run(self): + if GENERATOR_PROCESS: + generate_process = Process(target=Scheduler.generate_cookie) + generate_process.start() + + if VALID_PROCESS: + valid_process = Process(target=Scheduler.valid_cookie) + valid_process.start() + + if API_PROCESS: + api_process = Process(target=Scheduler.api) + api_process.start() + diff --git a/cookiespool/tester.py b/cookiespool/tester.py new file mode 100644 index 0000000..0070e70 --- /dev/null +++ b/cookiespool/tester.py @@ -0,0 +1,61 @@ +import json +from bs4 import BeautifulSoup +import requests +from requests.exceptions import ConnectionError +from cookiespool.db import * +from cookiespool.generator import WeiboCookiesGenerator + + +class ValidTester(object): + def __init__(self, name='default'): + self.name = name + self.cookies_db = CookiesRedisClient(name=self.name) + self.account_db = AccountRedisClient(name=self.name) + + def test(self, account, cookies): + raise NotImplementedError + + def run(self): + accounts = self.cookies_db.all() + for account in accounts: + username = account.get('username') + cookies = self.cookies_db.get(username) + self.test(account, cookies) + + +class WeiboValidTester(ValidTester): + def __init__(self, name='weibo'): + ValidTester.__init__(self, name) + + def test(self, account, cookies): + print('Testing Account', account.get('username')) + try: + cookies = json.loads(cookies) + except TypeError: + # Cookie 格式不正确 + print('Invalid Cookies Value', account.get('username')) + self.cookies_db.delete(account.get('username')) + print('Deleted User', account.get('username')) + return None + try: + response = requests.get('http://weibo.cn', cookies=cookies) + if response.status_code == 200: + html = response.text + soup = BeautifulSoup(html, 'lxml') + title = soup.title.string + if title == '我的首页': + print('Valid Cookies', account.get('username')) + else: + print('Title is', title) + # Cookie已失效 + print('Invalid Cookies', account.get('username')) + self.cookies_db.delete(account.get('username')) + print('Deleted User', account.get('username')) + except ConnectionError as e: + print('Error', e.args) + print('Invalid Cookies', account.get('username')) + + +if __name__ == '__main__': + tester = WeiboValidTester() + tester.run() diff --git a/cookiespool/verify.py b/cookiespool/verify.py new file mode 100644 index 0000000..9207904 --- /dev/null +++ b/cookiespool/verify.py @@ -0,0 +1,137 @@ +import requests +import time +from requests.exceptions import ConnectionError +from cookiespool.config import * + + +class Yundama(): + def __init__(self, username, password, app_id, app_key, api_url=YUNDAMA_API_URL): + self.username = username + self.password = password + self.app_id = str(app_id) if not isinstance(app_id, str) else app_id + self.app_key = app_key + self.api_url = api_url + + def login(self): + """ + 登录云打码账户 + :return: + """ + try: + data = {'method': 'login', 'username': self.username, 'password': self.password, 'appid': self.app_id, + 'appkey': self.app_key} + response = requests.post(self.api_url, data=data) + if response.status_code == 200: + result = response.json() + print(result) + if 'ret' in result.keys() and result.get('ret') < 0: + return self.error(result.get('ret')) + else: + return result + return None + except ConnectionError: + return None + + def upload(self, files, timeout, code_type): + """ + 上传验证码得到识别结果 + :param files: + :param timeout: + :param code_type: + :return: + """ + try: + data = {'method': 'upload', 'username': self.username, 'password': self.password, 'appid': self.app_id, + 'appkey': self.app_key, 'codetype': str(code_type), 'timeout': str(timeout)} + response = requests.post(self.api_url, data=data, files=files) + if response.status_code == 200: + return response.json() + return None + except ConnectionError: + return None + + def retry(self, cid, try_count=1): + """ + 临时识别不出, 传入cid重试 + :param cid: 验证码ID + :param try_count: 重试次数 + :return: 验证码结果 + """ + if try_count >= YUNDAMA_MAX_RETRY: + return None + print('Retrying: ', cid, 'Count: ', try_count) + time.sleep(2) + try: + data = {'method': 'result', 'cid': cid} + print(data) + response = requests.post(self.api_url, data=data) + if response.status_code == 200: + result = response.json() + print(result) + if 'ret' in result.keys() and result.get('ret') < 0: + print(self.error(result.get('ret'))) + if result.get('ret') == 0 and 'text' in result.keys(): + return result.get('text') + else: + return self.retry(cid, try_count + 1) + return None + except ConnectionError: + return None + + def identify(self, file=None, stream=None, timeout=60, code_type=5000): + """ + 主函数 + :param file: 文件名 + :param stream: 文件流, 优先于文件名 + :param timeout: 超时时间 + :param code_type: 验证码类型 + :return: 识别结果 + """ + if stream: + files = {'file': stream} + elif file: + files = {'file': open(file, 'rb')} + else: + return None + result = self.upload(files, timeout, code_type) + if 'ret' in result.keys() and result.get('ret') < 0: + print(self.error(result.get('ret'))) + if result.get('text'): + print('验证码识别成功', result.get('text')) + return result.get('text') + else: + return self.retry(result.get('cid')) + + def error(self, code): + """ + 报错原因 + :param code: 错误码 + :return: 错误原因 + """ + map = { + -1001: '密码错误', + -1002: '软件ID/密钥有误', + -1003: '用户被封', + -1004: 'IP被封', + -1005: '软件被封', + -1006: '登录IP与绑定的区域不匹配', + -1007: '账号余额为零', + -2001: '验证码类型有误', + -2002: '验证码图片太大', + -2003: '验证码图片损坏', + -2004: '上传验证码图片失败', + -3001: '验证码ID不存在 ', + -3002: '验证码还在识别', + -3003: '验证码识别超时', + -3004: '验证码看不清', + -3005: '验证码报错失败', + -4001: '充值卡号不正确或已使用', + -5001: '注册用户失败' + } + return '云打码' + map.get(code) + + +if __name__ == '__main__': + ydm = Yundama(YUNDAMA_USERNAME, YUNDAMA_PASSWORD, YUNDAMA_APP_ID, YUNDAMA_APP_KEY) + result = ydm.identify(file='getimage.jpg') + print(result) diff --git a/run.py b/run.py new file mode 100644 index 0000000..9755ab0 --- /dev/null +++ b/run.py @@ -0,0 +1,8 @@ +from cookiespool.scheduler import Scheduler + +def main(): + s = Scheduler() + s.run() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/tests/login.py b/tests/login.py new file mode 100644 index 0000000..a70580b --- /dev/null +++ b/tests/login.py @@ -0,0 +1,17 @@ +import requests +from bs4 import BeautifulSoup + +cookies = { + 'SSOLoginState': '1493555070', + 'SCF': 'ArrMd41qtHmW87eTIsI-sT1IjDG8oncB9A0HbSmyDw1FwO5sbI_j6_ZellQQ07ZjTXTIBrM3Y_tpKym39f1tYWs.', + 'SUB': '_2A250AacuDeRhGeRG6FIX9ybIzDiIHXVXDclmrDV6PUJbktBeLVfCkW18FWjD8r3ddYXy2abmqSauclujaw..', + '_T_WM': '5e9c698a350ddeba1c5d77e1958af21b', 'ALF': '1496147067', 'SUHB': '0G0vWR88D2VokZ', + 'SUBP': '0033WrSXqPxfM725Ws9jqgMF55529P9D9W5APD86CuQDllBusA-6OZaq5JpX5o2p5NHD95QE1he7SoMRShMXWs4Dqcjci--fi-zXiK.Xi--fi-iWiKnci--ciKn4iKy2i--Xi-zRi-2Ri--4iKL2iK.4i--Ri-2NiKnf' +} + +response = requests.get('http://weibo.cn', cookies=cookies) +if response.status_code == 200: + html = response.text + soup = BeautifulSoup(html, 'lxml') + title = soup.title.string + print(title)