搞SEO的,查询关键词排名是常见需求。今天就以Python查询百度移动端前5页排名为例,介绍如何使用Python实现查排名这样一个简单需求。
查询前5页排名,首先需要遍历移动端百度搜索结果前5页,提取每条搜索结果对应的URL和排名。然后判断要查询的域名是否包含在URL当中,如果在,就返回排名。如果不在,就返回“50+”,表示排名在50名开外或没有排名。
考虑到查询每个关键词排名需要请求5次搜索结果,查询速度相对来说会比较慢。开启多线程,可以提升查询效率,这里使用multiprocessing库来实现多线程。HTML解析使用pyquery库,第三方库需安装,pip install pyquery即可。代码示例:
import requests,urllib,json
from pyquery import PyQuery as pq
from multiprocessing.dummy import Pool as ThreadPool
from functools import partial
headers = {'User-Agent':'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5'}
def curl(url,retries = 3,num = 1):
try:
html = requests.get(url, headers = headers,timeout = 5).text
except:
html = None
if retries > 0:
print('请求失败,重试第%s次' % num)
return curl(url,retries - 1,num + 1)
return html
def baidu_urls(kw):
urls = []
ranks = []
for i in range(0,50,10):
url = 'https://m.baidu.com/s?word={}&pn={}'.format(urllib.parse.quote(kw),i)
try:
html = curl(url)
doc = pq(html)
divs = doc('.result').items()
for div in divs:
datalog = div.attr('data-log')
if datalog:
datalog = datalog.replace('\'','"')
data = json.loads(datalog)
url = data.get('mu','404.html')
urls.append(url)
rank = i + int(data.get('order'))
ranks.append(rank)
except:
continue
return zip(urls,ranks)
def mobrank(kw,domain):
print(kw)
datas = baidu_urls(kw)
for url,rank in datas:
if domain in url:
return kw,url,rank
return kw,'404.html','50+'
kws = [kw.rstrip() for kw in open('keywords.txt',encoding='utf-8-sig')]
datas = []
from multiprocessing.dummy import Pool as ThreadPool
pool = ThreadPool(25) #开启25个线程
results = pool.map(partial(mobrank,domain='带查询域名'),kws) #这里传入带查询的域名
pool.close()
pool.join()
for kw,url,rank in results:
data = '{}\t{}\t{}'.format(kw,url,rank)
datas.append(data+'\n')
print(data)
with open('results.txt','w',encoding='utf-8') as f: #将查询结果写入TXT文件
f.writelines(datas)
关键词保存在keywords.txt文件中,一行一个,将待查询域名修改成你要查询的域名,运行脚本即可。查询完毕后,查询结果将保存在results.txt文件中。
经测试,查询4400个关键词历时1700秒左右,查询速度不是很快,但也足够用了。
网上关于使用multiprocessing.dummy多线程的例子都比较简单,只传入一个参数。利用functools模块中的partial方法可以实现多个参数传入。
PS:关注公众号后回复关键词【移动排名】即可获取这个脚本,不会使用私信我。