【Python+SEO编程实战】抓取百度相关搜索词

2017年10月16日07:00:01 发表评论

和朋友商量初步定义了几个SEO工具的需求,计划使用Python实现:

1、指定规则,扫描并导出网站所有有效URL
2、批量抓取页面的标题,判断SERP前三页是否存在(判断索引)
3、批量寻找关键词前N页所有搜索结果,并且导出标题和URL(用于寻找外链资源)
4、批量抓取页面的标题,判断当前搜索引擎内标题相似度(判断标题是否可用)
5、指定第一个词汇,抓取搜索引擎相关搜索,并用结果词导出结果词 相关搜索词,并导出,重复N次。(关键词库,内部链接提升页面相关性)
6、 服务器日志批处理,利用PY实现,日志批量筛选和有效导出。
7、通过违规词列表,扫描指定页面是否出现违规词汇。

希望靠这些实例编程,让大家获得python可以帮我解决实际问题的印象,跟着简单修改下就用在实际的工作中。

本次以第5个需求为例,完成一段实现的python代码,主要目的是抓取百度相关搜索词。

为了满足实际应用,把这个需求进行了拓展:

A、支持输入多个词,进行百度相关搜索词拓展。

B、可以指定要求必须包含什么词,或不能包含什么词。

C、可以把采集到的词存为txt文件,可自定义文件名。

以后可以进一步完善的工作:

1、多线程采集

2、使用代理IP采集

3、更多容错判断

下面为具体代码,为了方便理解,几乎每行都有注解,不要嫌弃啰嗦。

# coding = utf-8
'''
1、指定关键词,抓取搜索引擎相关搜索词,并使用结果词再次抓取其相关搜索词。
2、采集时对搜索相关词做处理,必须包含某些关键词或不能包含的词才作为有效词。
3、指定希望获得的最终相关词数量。

获得的搜索相关词用途:增加关键词库,提升内部链接相关性,分析用户的搜索行为,广告投放等等。

'''
#导入http请求库request
import requests
#导入随机数库
import random
#导入时间库
import time
#导入日期库
import datetime
# 导入URL解析库
from urllib import parse
# 导入BeautifulSoup库,使用别名bs
from bs4 import BeautifulSoup as bs

# 定义获取相关词的函数,@words是希望拓展的词根列表,@num是希望获取的相关词数量(大概)
def get_related_words(words, num=10):
	for word in words:
		# 当已有词数量小于希望获取的词数时
		if(len(words) < num):	
			# 对词做urlencode的,解决中文URL的问题
			word = parse.quote_plus(word)
			# 构造请求的网址
			url = 'https://www.baidu.com/s?ie=utf-8&wd=' + word 
			# 构造 http headers里的内容
			headers = {}
			# 构造随机UA
			headers['User-Agent'] = "Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0" + str(random.randint(1,99))
			# Referer 地址
			headers['Referer'] = url
			# 超时设为10秒,如果网页10秒内无响应抛出异常
			timeout = 10
			# 发送请求
			res = requests.get(url, headers = headers, timeout = timeout)
			# 获取页面的响应状态码(200/404/301等)
			http_status = res.status_code
			# 获取待采集页面的编码(UTF-8,GBK等编码)
			res_encoding = res.encoding
			# 获得采集页面的HTML代码,转化为UTF8编码,避免乱码问题
			html_code = res.text.encode(res.encoding).decode('utf8')
			# 把HTML代码转化为用Beautiful Soup变成DOM对象,解析内核使用lxml,效率高
			soup = bs(html_code, "lxml")
			# 获取搜索相关词对应的A元素
			element = soup.select("#rs a")
			# res = []
			for i in element:
				# 获得相关词的文本并去掉左右的空格
				item = i.get_text().strip()
				# 如果相关词不在之前的列表中则加入
				if item not in words:
					print("运行中..."+"\n")
					words.append(item)
			# 休息3秒,防止被百度封
			time.sleep(3)
		else:
			break
	# 返回获得的关键词数组
	return words

# 把列表数据按指定的文件名写入文件,如不指定文件名,则使用程序运行时间作为文件名。例如:20171010-12-10-09.txt
def save_to_file(list, filename=None):
	# 当指定文件名时
	if filename is not None:
		# 使用txt作为扩展名,方便使用
		filename = filename + '.txt'
	# 当没有指定文件名时
	else:
		# 根据程序启动时间格式化作为文件名
		filename = str(datetime.datetime.now().strftime('%Y%m%d-%H-%M-%S')) + '.txt'	
	# 把列表数据写入文件,第一个参数是文件名,第二个参数'w'为打开模式,w代表写文本文件,wb代表写二进制文件,w+表示追加写文件
	with open(filename, 'w') as f:
		for i in list:
			# 一行写入一个词,"\n"为换行符
			f.write(i+"\n")
	
	# 提示保存的文件名
	print("已写入文件:{0}".format(filename))

# 打印输出列表数据,使用样式区分,便于理解
def print_list(list):
	# 前面空一行,然后输出头标题
	print("\n"+"************输出结果如下:**************")
	# 循环打印数据
	for i in list:		
		print(i)
	# 使用40个*号分隔,之后空一行
	print("*"*40+"\n")

# 定义词筛选过滤规则,@ori_list是全部相关词的列表,@must_contain为必须包含的关键词列表,@should_not_contain为不能包含的关键词列表
def filter_words(ori_list, must_contain=None, should_not_contain=None):
	# 定义一个空列表,用于存储过滤后的结果,rs为result的简写
	rs = []
	# 循环所有列表中的词
	for i in ori_list:
		# 如果定义了不能包含的词
		if should_not_contain is not None:
			# 循环不能包含的词列表
			for wd in should_not_contain:
				# 如果相关词包含不允许的词,则继续往下走
				if(i.find(wd.lower())>=0):
					continue
				# 如果没有包含不允许的词,则进入下面的处理过程
				else:
					# 如果定义了必须包含的词
					if must_contain is not None:
						# 循环必须包含的词
						for w in must_contain:	
							# 把w都转换为小写字符,因为百度搜索相关词中英文都是小写,之后查询是否包含必须有的词(>=0表示至少包含一次)		
							if i.find(w.lower())>=0:
								rs.append(i)
					# 如果没有定义必须包含的词,则所有词直接加入列表中。
					else:
						rs.append(i)
		# 如果没有定义不能包含的词
		else:
			# 解释同上
			if must_contain is not None:
				for w in must_contain:			
					if i.find(w.lower())>=0:
						rs.append(i)
			else:
				rs.append(i)
	# 返回最终过滤后的词列表
	return rs


# 打算拓展的词根
root_words = ['QQ', '腾讯']
# 根据词根进行相关词采集,指定最终采集词量
words = get_related_words(root_words, 30)

# 定义必须包含的关键词列表
must_contain = ['大全']
# 定义不能包含的关键词列表
should_not_contain = ['手游']


# 输出不加任何过滤规则获得的相关搜索词

rule1 = filter_words(words)
print("不加任何过滤规则获得的相关搜索词")
print_list(rule1)

rule2 = filter_words(words, must_contain)
print("指定必须包含的关键词后获得的相关搜索词")
print_list(rule2)

rule3 = filter_words(words, must_contain, should_not_contain)
print("指定必须包含的关键词和不能包含的关键词后获得的相关搜索词")
print_list(rule3)

# 把不同过滤规则处理后获得的词写入指定的文件中
save_to_file(rule1, 'all_words')
save_to_file(rule2, 'must_contain_words')
save_to_file(rule3, 'filter_words')

# 不做过滤处理,也不指定文件名,按程序启动时间作为文件名保存结果。
save_to_file(words)

# 输出实际获得的总词数
print("总共词数:{0}".format(len(rule1)))
print("必须包含指定词数量:{0}".format(len(rule2)))
print("最严过滤规则词:{0}".format(len(rule3)))
  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信公众号扫一扫
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: