百度移动相关搜索词挖掘脚本(多线程版),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,完成挖掘')