前言
这学期有门课是信息检索(Information Retrieval),老师布置的大作业是制作一个简单的搜索引擎。先提前学一点,随时更新。欢迎大家交流指导!
总体流程
Flask框架
这里就省去介绍了,在app.py中最简单地先创建一个搜索的首页:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template("index.html")
if __name__ == '__main__':
app.run()
这里学习了一个小技巧,首页在写html文件时,以百度为例,可以直接F12查看并复制代码到html文件中。可以较为简单的copy基础样式。
如上图,我们把输入框和“百度一下”的按钮复制到index.html页面中 其实就多了body中的两行,分别是文本框和搜索按钮。还需要用一个form表单把body包起来,使得用户点击按钮可以把输入内容提交到名为“/s”的路由,也就是传到后端。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Search Engine</title>
</head>
<body>
<form action="/s" method="get">
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
<input type="submit" value="Search" id="su" class="btn self-btn bg s_btn">
</form>
</body>
</html>
打开html看一下,还凑合,省去自己写了。 给用户返回其搜索的相关信息需要用简单的爬虫来实现。
需要首先简单分析一下百度搜索的过程,我们以搜索一个人名为例 页面上方出现了一长串url,我们通过不断删减,发现有好多看不懂的信息都是没有必要的,只保留最关键的wd=武忠祥就能出现一样的结果(核心url就是https://www.baidu.com/s?wd=)。而wd就是用户输入的keyword,即搜索内容。并且只需更换wd后面的关键字,返回到页面的内容也会更改
爬虫
新建一个文件spider.py,定义一个函数来获取百度的页面内容。用到了requests库中的get方法,wd后面的关键字用python格式化输入来填入keyword,之后返回页面源码。
import requests
# https://www.baidu.com/s?wd=武忠祥
def get_search(keyword):
res = requests.get('https://www.baidu.com/s?wd={}'.format(keyword))
result = res.text # 搜索结果百度页面的源码
return result
简单测试一下,先把返回的result打印出来
import requests
# https://www.baidu.com/s?wd=武忠祥
def get_search(keyword):
res = requests.get('https://www.baidu.com/s?wd={}'.format(keyword))
result = res.text # 搜索结果百度页面的源码
print(result)
get_search("https://www.baidu.com/s?wd=武忠祥")
结果是以下html代码
<html>
<head>
<script>
location.replace(location.href.replace("https://","http://"));
</script>
</head>
<body>
<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
随便新建一个html文件,将上述代码复制进去,打开此网页发现,得到了一个空白页面,不是我们想要的结果。原因是百度做了反爬机制!
还好破解这个反爬只需要很简单的操作,只需添加一个headers请求头就OK了。具体步骤如下:
- 在搜索页面F12
- 点击NetWork,若为空白先刷新一下页面
- 找到某一条中的User-Agent,将其复制到函数中
- requests.get函数中添加参数headers=headers
原理其实很简单:User-Agent里的信息其实就是我们访问这个页面的浏览器的信息,通过单词User-Agent直译为用户代理,也能猜测出来,是浏览器代理帮我们返回了信息。而我们通过requests去访问百度的url时,需要模拟成为浏览器,让服务器以为我们就是通过浏览器来搜索信息的,这样才能成功破解反爬。
import requests
# https://www.baidu.com/s?wd=武忠祥
def get_search(keyword):
headers = {
# 浏览器的信息(模拟浏览器)
"User-Agent": "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
"(KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 "
}
res = requests.get('https://www.baidu.com/s?wd={}'.format(keyword), headers=headers)
result = res.text # 搜索结果百度页面的源码
print(result)
get_search("https://www.baidu.com/s?wd=武忠祥")
再一打印会出现一段极长的html代码,一看就靠谱!肯定是我们要的搜素结果!
最后把get_search函数结尾改为return result。然后完善app.py中的“/s”搜索路由。
from flask import Flask, render_template, request
from spider import get_search
app = Flask(__name__)
@app.route('/')
def index():
return render_template("index.html")
@app.route('/s')
def s():
keyword = request.args.get('wd') # 获取用户输入关键字
return get_search(keyword)
if __name__ == '__main__':
app.run()
大功告成!!!
最终结果
运行程序,输入关键字 点击搜索,就会像百度一样出现搜索结果,但是是在自己的域名下,再做一些前端的优化就可以改造成自己的搜索引擎!
总结
此简易搜索引擎以Flask为框架,首先搭建简单的首页,使用户点击搜索按钮后可以在后台获取keyword。之后通过分析百度搜索结果的url,通过简单的爬虫获取到百度的搜索结果。过程中用到了添加请求头这一最简单的反爬方法。最后将获取的结果返回到页面上。具体也可参考文章最前面的流程图。简单概括如下:
- 搭建页面
- 获取用户输入
- 通过爬虫获取百度搜索结果(需要简单破解反爬)
- 将搜索结果显示在页面上
欢迎大家交流指导!
|