Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions send_msg_with_mongo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import datetime
import time
from wxpy import *
from pymongo import MongoClient
from pymongo.collection import Collection
from xianyu import return_result, loop_reply
import threading
client = MongoClient() # 里面什么都不填的话, 默认localhost, 27017
killer_test = client['killer_test']
config_list = Collection(killer_test, 'config_list')

bot = Bot(cache_path = True)
print('Welcom to Killer\'s World')
friend_list = bot.friends()
# 这里配置我们想要什么信息
# msg.text.startswith('搜索关键词:') 这个写在判断语句里, 也是我们想要的信息
WORD_DICT = {
'keyword': ['配置信息', '配置', '1', '2']
}


@bot.register(friend_list, TEXT)
def auto_reply(msg):
print(msg.text)
if msg.text in WORD_DICT['keyword'] or msg.text.startswith('搜索关键词:'):
# 如果用户输入 '配置信息' 或者 '配置'
if msg.text == '配置信息' or msg.text == "配置":
print(msg.sender.name,':', msg.text, 'MSG_TYPE:', msg.type)
return '请按格式回复你的配置信息,格式如下,请把内容替换成你的内容:\n搜索关键词:麻瓜编程、自动办公、实用主义学Python'

# 如果用户输入的以搜索关键词:开头的储存进数据库
if msg.text.startswith('搜索关键词:') and len(msg.text.strip()) > 6:
print(msg.text)
config = {}
config['is_sure'] = 0
config['user_name'] = msg.sender.name
config['query_list'] = [i.strip() for i in msg.text.lstrip('搜索关键词:').split('、') if len(i.strip())>0]
if len(config['query_list']) == 0:
return '请按格式回复你的配置信息,格式如下,请把内容替换成你的内容:\n搜索关键词:麻瓜编程、自动办公、实用主义学Python'
config['is_crawled'] = False
config['crawled_time'] = None

# 这里应该添加一个判断, 就比如用户 输入了两遍 搜索关键词:麻瓜编程、自动办公、实用主义学Python
# 搜索关键词:麻瓜编程、自动办公、实用主义学Python
# 如果数据库里有这个用户配置的信息 就让用户回复1 和 2 否则就插入数据库
print(config)
# 我们先插数据库里是否有这个用户的设置记录, 若果有就让他按 2 清除
user = config_list.find_one({'user_name':msg.sender.name, 'is_sure': 1, 'is_crawled': True})
if user is not None:
return f'你之前提交过配置 配置的信息如下:\n搜索关键词:{"、".join(user["query_list"])}\n如需修改请回复 2'
# else 证明数据库里没有这个用户的爬取数据 则判断用户是否已经设置过一次
else:
user = config_list.find_one({'user_name':msg.sender.name, 'is_sure': 0, 'is_crawled': False})
if user is not None:
# if len(user) > 0 :
return f'你之前提交过配置 配置的信息如下:\n搜索关键词:{"、".join(user["query_list"])}\n确认请回复 1\n如需修改请回复 2'
else:
config_list.insert(config)

return f'你配置的信息如下:\n {msg.text}\n确认请回复 1\n如需修改请回复 2'


# 如果用户会回复的是1 就说明要 确认 搜索关键词
if msg.text == '1':
user = config_list.find_one({'user_name':msg.sender.name, 'is_sure': 1, 'is_crawled': True})
if user is not None:
return f'你之前提交过配置 配置的信息如下:\n搜索关键词:{"、".join(user["query_list"])}\n如需重新配置请回复 2'
# else 证明数据库里没有这个用户的爬取数据 则判断用户是否已经设置过一次
else:
user = config_list.find_one({'user_name':msg.sender.name, 'is_sure': 0, 'is_crawled': False})
if user is not None:
print('找到了该用户%s' %msg.sender.name)
config_list.update({'user_name':msg.sender.name, 'is_sure': 0, 'is_crawled': False}, {'$set': {'is_sure': 1}})
msg.reply('配置成功,请稍后')
return_result(user, msg, config_list)
else:
return '你还没有配置\n请按格式回复你的配置信息,格式如下,请把内容替换成你的内容:\n搜索关键词:麻瓜编程、自动办公、实用主义学Python'

# 如果用户输入的是2 就要删除数据库中的记录 可以做逻辑删除, 我这里直接物理删除了
if msg.text == '2':
user = config_list.find_one({'user_name':msg.sender.name})
if user is not None:
config_list.remove({'user_name':msg.sender.name})
return '请按格式回复你的配置信息,格式如下,请把内容替换成你的内容:\n搜索关键词:麻瓜编程、自动办公、实用主义学Python'
else:
return '你还没有配置\n请按格式回复你的配置信息,格式如下,请把内容替换成你的内容:\n搜索关键词:麻瓜编程、自动办公、实用主义学Python'
# 如果输入的文本 不在 WORD_DICT 中或者 不是以搜索关键词:开头的话
# 这里如果是自己的微信号的话 建议注释掉。。。。
# else:
# return '少侠你又调皮了 配置信息有误\n请按格式回复你的配置信息,格式如下,请把内容替换成你的内容:\n搜索关键词:麻瓜编程、自动办公、实用主义学Python'


# 自动添加好友并回复 我是盗版杀手机器人,请通过回复 "配置" 来配置你的信息
@bot.register(msg_types=FRIENDS)
def auto_accept_friends(msg):
# 接受好友请求
new_friend = msg.card.accept()
# 向新的好友发送消息
new_friend.send('我是一个没有感情的盗版杀手机器人,请通过回复 "配置" 来配置你的信息')

# 每日自动发送
# 测试用的 每隔5分钟。。。
def _main():
while True:
for user in config_list.find({}):
time_now = datetime.datetime.now()
if user['is_crawled'] == True and time_now > user['crawled_time'] + datetime.timedelta(minutes=1):
# if user['is_crawled'] == True and user['crawled_time'] + datetime.timedelta(hours=24) > time_now:
friend = bot.friends().search(name=user['user_name'])[0]
loop_reply(friend, user, config_list)
# 这里设计有缺陷
time.sleep(60)


t = threading.Thread(target=_main)
t.start()

embed()
# bot.join()
Binary file added wxpy.pkl
Binary file not shown.
151 changes: 151 additions & 0 deletions xianyu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import re
import time
import requests
import datetime
from fake_useragent import UserAgent
from lxml import etree
# 不能从send_msg_with_mongo 导入 我就把这边的函数引过去。。。。
# from send_msg_with_mongo import config_list, friend_list

ua = UserAgent()
headers = {
'User-Agent': ua.random
}

def get_you_want(query):
url = f'https://s.2.taobao.com/list/?_input_charset=utf8&ist=1&q={query}'
resp = requests.get(url, headers=headers).text
urls = []
try:
total_page = int(re.findall("共(\d+)页", resp)[0])
# 我们这里返回前10页就够了, 100页的商品 后面基本都是没用的
if total_page > 10:
total_page = 10
for i in range(1, total_page+1):
url = f'https://s.2.taobao.com/list/?_input_charset=utf8&ist=1&q={query}&page={i}'
urls.append(url)
return urls
except:
return None

def parse_pub_time(pub_time):
if '分钟' in pub_time:
num = int(re.search('\d+', pub_time).group())
pub_time = datetime.datetime.now() - datetime.timedelta(minutes=num)
elif '小时' in pub_time:
num = int(re.search('\d+', pub_time).group())
pub_time = datetime.datetime.now() - datetime.timedelta(hours=num)
elif '天' in pub_time:
num = int(re.search('\d+', pub_time).group())
pub_time = datetime.datetime.now() - datetime.timedelta(days=num)
elif '月' in pub_time:
num = int(re.search('\d+', pub_time).group())
pub_time = datetime.datetime.now() - datetime.timedelta(days=30*num)
elif '年' in pub_time:
num = int(re.search('\d+', pub_time).group())
pub_time = datetime.datetime.now() - datetime.timedelta(days=365*num)
return pub_time


def parse_page_auto(url, data_list, query, user):
resp = requests.get(url, headers=headers).text
time.sleep(1)
html = etree.HTML(resp)
items = html.xpath("//div[contains(@class, 'ks-waterfall')]")[1:]
for item in items:
item_id = item.xpath('.//div[@class="item-pic"]/a/@href')[0].split('=')[-1]
data = {
'title': item.xpath('.//div[@class="item-pic"]/a/@title')[0],
'img': item.xpath('.//div[@class="item-pic"]/a/img/@src')[0],
'href': 'https:' + item.xpath('.//div[@class="item-pic"]/a/@href')[0],
'item_id': item_id,
'desc': item.xpath('.//div[@class="item-brief-desc"]/text()')[0],
'price': item.xpath('.//span[@class="price"]/em/text()')[0],
'location': item.xpath('.//div[@class="item-location"]/text()')[0],
'pub_time': parse_pub_time(item.xpath('.//span[@class="item-pub-time"]/text()')[0]),
'app_link': 'https://market.m.taobao.com/app/idleFish-F2e/widle-taobao-rax/page-detail?wh_weex=true&wx_navbar_transparent=true&id=' + item_id
# 'is_sold': False
}
# 这里最好判断一下关键词在不在里面。。。 设置个办公自动化 美容美体床、自动双面激光打印机都给我出来了。。。
# 如果第一爬的话 就全部返回 第一次爬
if query in data['title'] or query in data['desc']:
# if user['crawled_time'] is None:
print(f"{query} 新发现一个盗版商品-{data['title']}-{data['href']}")
data_list.append(data)

def return_result(user, msg, config_list):
query_list = user['query_list']
print(query_list)
# query = '麻瓜编程'
for query in query_list:
data_list = []
urls = get_you_want(query)
if urls:
for url in urls:
parse_page_auto(url, data_list, query, user)
if len(data_list) > 0:
for data in data_list:
msg.reply(f"{query} 新发现一个盗版商品-{data['title']}-{data['href']}\napp链接为:{data['app_link']}")
time.sleep(1)
msg.reply('-----------------------')
else:
msg.reply('没有找到相关的信息 %s' %query)
msg.reply('回复完毕, 请查看!')
# 更新用户 是否已经爬取 是 。这里不保存信息的话也可以从数据库直接删除
config_list.update({'user_name':user['user_name'], 'is_sure': 1, 'is_crawled': False},{"$set":{'is_crawled': True, 'crawled_time':datetime.datetime.now()}})


def parse_page(url, data_list, query, user):
resp = requests.get(url, headers=headers).text
time.sleep(1)
html = etree.HTML(resp)
items = html.xpath("//div[contains(@class, 'ks-waterfall')]")[1:]
for item in items:
item_id = item.xpath('.//div[@class="item-pic"]/a/@href')[0].split('=')[-1]
data = {
'title': item.xpath('.//div[@class="item-pic"]/a/@title')[0],
'img': item.xpath('.//div[@class="item-pic"]/a/img/@src')[0],
'href': 'https:' + item.xpath('.//div[@class="item-pic"]/a/@href')[0],
'item_id': item_id,
'desc': item.xpath('.//div[@class="item-brief-desc"]/text()')[0],
'price': item.xpath('.//span[@class="price"]/em/text()')[0],
'location': item.xpath('.//div[@class="item-location"]/text()')[0],
'pub_time': parse_pub_time(item.xpath('.//span[@class="item-pub-time"]/text()')[0]),
'app_link': 'https://market.m.taobao.com/app/idleFish-F2e/widle-taobao-rax/page-detail?wh_weex=true&wx_navbar_transparent=true&id=' + item_id
# 'is_sold': False
}
print(f"pub_time:{data['pub_time']}, crawled_time:{user['crawled_time']}")
# 这里最好判断一下关键词在不在里面。。。 设置个办公自动化 美容美体床、自动双面激光打印机都给我出来了。。。
# 如果第一爬的话 就全部返回 第一次爬
if query in data['title'] or query in data['desc']:
if data['pub_time'] > user['crawled_time']:
print(f"{query} 新发现一个盗版商品-{data['title']}-{data['href']}")
data_list.append(data)




def loop_reply(friend, user, config_list):
# 更新用户 是否已经爬取 是 。这里不保存信息的话也可以从数据库直接删除
config_list.update({'user_name':user['user_name'], 'is_sure': 1, 'is_crawled': True},{"$set":{'crawled_time':datetime.datetime.now()}})

query_list = user['query_list']
print(query_list)
# query = '麻瓜编程'
for query in query_list:
data_list = []
urls = get_you_want(query)
print(urls)
if urls:
for url in urls:
parse_page(url, data_list, query, user)
if len(data_list) > 0:
for data in data_list:
friend.send(f"{query} 新发现一个盗版商品-{data['title']}-{data['href']}\napp链接为:{data['app_link']}")
time.sleep(1)
friend.send('-----------------------')
else:
friend.send('没有找到相关的信息 %s' %query)
friend.send('回复完毕, 请查看!')