百度移动相关搜索词挖掘脚本(多线程版),
keywords.txt,挖掘词存放
seo.txt 挖掘词seo难易度,值越大越简单,越能获取利率
faileds.txt,挖掘失败关键词
baidumobilekey.txt,挖掘结果存放
免费版:
import re from queue import Queue from threading import Thread import requests class BdMobileSpider(Thread): result = {} # 保存结果字典 seen = set() # 表示在队列中的关键词(已抓取或待抓取) def __init__(self, kw_queue, loop, failed): super(BdMobileSpider, self).__init__() self.kw_queue = kw_queue # 关键词队列 self.loop = loop # 循环挖词拓展次数 self.failed = failed # 保存查询失败的关键词文件 self.ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 ' \ '(KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1' def run(self): # 程序的执行流程 while True: # 从队列里面获取一个关键词及其对应的当前拓展次数 kw,cloop = self.kw_queue.get() print('CurLoop:{} Checking: {}'.format(cloop,kw)) query = 'https://m.baidu.com/s?word={}'.format(kw) # 构建含关键词的url try: source = self.download(query,timeout=10,user_agent=self.ua) if source: kw_list = self.extract(source) self.filter(cloop, kw_list) else: # 获取源码失败,保存查询失败的关键词 self.failed.write('{}\n'.format(kw)) finally: self.kw_queue.task_done() def download(self,url,timeout=5,user_agent='dyspider',proxy=None,num_retries=5): """ 通用网页源码下载函数 :param url: 要下载的url :param timeout: 请求超时时间,单位/秒。可能某些网站的反应速度很慢,所以需要一个连接超时变量来处理。 :param user_agent: 用户代理信息,可以自定义是爬虫还是模拟用户 :param proxy: ip代理(http代理),访问某些国外网站的时候需要用到。必须是双元素元组或列表(‘ip:端口’,‘http/https’) :param num_retries: 失败重试次数 :return: HTML网页源码 """ headers = {'User-Agent': user_agent} try: # 打开网页并读取内容存入html变量中 resp = requests.get(url,headers=headers, proxies=proxy, timeout=timeout) except requests.RequestException as err: print('Download error:',err) html = None # 如果有异常,那么html肯定是没获取到的,所以赋值None if num_retries > 0: return self.download(url,timeout,user_agent,proxy,num_retries-1) else: html = resp.text return html @staticmethod def extract(html): ''' 提取关键词 :param html:搜索结果源码 :return:提取出来的相关关键词列表 ''' return re.findall(r'class="rw-item c-blocka" data-a-3c8eb21a>(.*?)</a>',html,re.S|re.I) def filter(self, current_loop, kwlist): ''' 关键词过滤和统计函数 :param current_loop: 当前拓展的次数 :param kwlist: 提取出来的关键词列表 :return: None ''' for kw in kwlist: # 判断关键词是不是已经被抓取或者已经存在关键词队列 # 判断当前的拓展次数是否已经超过指定值 if current_loop < self.loop and kw not in self.seen: # 同时满足关键词的拓展次数小于目标次数,而且关键词不在seen里面时才把kw放到待抓取队列内 self.kw_queue.put((kw, current_loop+1)) BdMobileSpider.seen.add(kw) # 将关键词放到结果字典内,并统计出现次数 if kw in self.result: BdMobileSpider.result[kw] += 1 else: BdMobileSpider.result[kw] = 1 if __name__ == '__main__': # 创建关键词队列实例 k_queue = Queue() # 将待抓取关键词放入队列已经类的seen属性中 with open('keywords.txt') as kwfile: for key in kwfile: key = key.strip() k_queue.put((key,1)) BdMobileSpider.seen.add(key) # 创建查询失败保存文件 check_failed = open('faileds.txt','w') # 创建线程 for i in range(15): bds = BdMobileSpider(k_queue, 3, check_failed) bds.setDaemon(True) bds.start() # 阻塞关键词队列,直到完成 k_queue.join() # 关闭查询失败的文件 check_failed.close() # 对结果进行排序及写入文件 sort_list = sorted(BdMobileSpider.result.items(), key=lambda x: x[1], reverse=True) save = open('baidumobilekey.txt', 'w', encoding='utf-8') for item in sort_list: # 关键词+次数的文件输出方式 line = '%s\t%d\n' % (item[0], item[1]) save.write(line) save.flush() # 刷新缓存,避免中途出错 save.close() print('done,完成挖掘')