自分のパソコンで、python検索エンジンを動かしたい!
問題解決です!
ここの記事にあるPython検索エンジンをなんとか動かしたいです。
https://github.com/c-data/pysearch
詳しい解説の記事
http://nwpct1.hatenablog.com/entry/python-search-engine
なんとか環境の構築まではうまくいきました。
Mac os
vagrantにubuntu14.04を仮想で起動し
VirtualenvでPython3を仮想にし以下のモジュールがインストールしてあります。
- Flask==0.12.2
- Janome==0.3.4
- Jinja2==2.9.6
- MarkupSafe==1.0
- Werkzeug==0.12.2
- beautifulsoup4==4.6.0
- certifi==2017.4.17
- chardet==3.0.4
- click==6.7
- idna==2.5
- itsdangerous==0.24
- pymongo==3.4.0
- requests==2.18.1
- urllib3==1.21.1
ubuntu14.04にMongodb 2.4.9 32bitがインストールしてあります。
あとはgithubにあったファイルをダウンロードしてコピーし
Mogodbを起動して
$ python manage.py crawler
実行すればデータベースにURLが保存されると思ったのですがエラーが出てしまいました。
(dev)ユーザ名:/vagrant/pysearch-master$ python manage.py crawler
Traceback (most recent call last):
File "manage.py", line 15, in <module>
crawl_web('http://docs.sphinx-users.jp/contents.html', 2)
File "/vagrant/pysearch-master/web_crawler/crawler.py", line 86, in crawl_web
add_page_to_index(page_url, html)
File "/vagrant/pysearch-master/web_crawler/crawler.py", line 73, in add_page_to_index
add_to_index(word, url)
File "/vagrant/pysearch-master/web_crawler/crawler.py", line 52, in add_to_index
entry = col.find_one({'keyword': keyword})
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/collection.py", line 1102, in find_one
for result in cursor.limit(-1):
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/cursor.py", line 1114, in next
if len(self.__data) or self._refresh():
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/cursor.py", line 1036, in _refresh
self.__collation))
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/cursor.py", line 873, in __send_message
**kwargs)
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/mongo_client.py", line 888, in _send_message_with_response
server = topology.select_server(selector)
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/topology.py", line 214, in select_server
address))
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/topology.py", line 189, in select_servers
self._error_message(selector))
pymongo.errors.ServerSelectionTimeoutError: mongo_url:27017: [Errno -2] Name or service not known
サーバーの接続がうまく出来ていないように見えるのですがどうしたらいいでしょうか?
crawler.py
このファイルのこの部分が怪しいと思うのですがどうしたらいいのかわかりません。
from config import MONGO_URL
#DBに接続
client = MongoClient(MONGO_URL)
#urlparseでURLのパスだけ抜き出す。それでデータベースを取得
db = client[urlparse(MONGO_URL).path[1:]]
#存在するIndexというデータベースを取り出す。
col = db["Index"]
config.py
あとはこの部分です。
import os
#接続先のホストはデフォルトだと ‘localhost’ でポート番号は 27017
# application settings
#os.environ.get('MONGOHQ_URL')通常のサーバーにアプリをあげるならこのようにしてURLを持ってくる必要があると思う。
MONGO_URL = 'MONGO_URL'
# Generate a random secret key
SECRET_KEY = os.urandom(24)
CSRF_ENABLED = True
新しいエラー
今度はデータベースの名前は空の文字列に出来ないみたいなことを言われているのですが、これはもともIndexって名前のデータベースをMongodbに作成しておかないといけないのでしょうか?
おそらく勝手に作成されると思うのですがどうなんでしょうか?
Traceback (most recent call last):
File "manage.py", line 14, in <module>
from web_crawler.crawler import crawl_web
File "/vagrant/pysearch-master/web_crawler/crawler.py", line 20, in <module>
db = cliet[urlparse(MONGO_URL).path[1:]]
NameError: name 'cliet' is not defined
(dev)vagrant@vagrant-ubuntu-trusty-32:/vagrant/pysearch-master$ python manage.py crawler
Traceback (most recent call last):
File "manage.py", line 14, in <module>
from web_crawler.crawler import crawl_web
File "/vagrant/pysearch-master/web_crawler/crawler.py", line 20, in <module>
db = client[urlparse(MONGO_URL).path[1:]]
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/mongo_client.py", line 996, in __getitem__
return database.Database(self, name)
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/database.py", line 106, in __init__
_check_name(name)
File "/home/vagrant/.virtualenvs/dev/local/lib/python3.4/site-packages/pymongo/database.py", line 42, in _check_name
raise InvalidName("database name cannot be the empty string")
pymongo.errors.InvalidName: database name cannot be the empty string
crawler.py引用
# -*- coding: utf-8 -*-
#pythonの標準のモジュールでurlからhtmlのファイルを持って来てくれる。
import requests
#pythonの標準のモジュールでurlの解析をしてくれる。
from urllib.parse import urlparse
#mongodbを操作する時に使用するモジュールでMongoClientでDBに接続する。
from pymongo import MongoClient
#日本語形態のやつを解析できる。
from janome.tokenizer import Tokenizer
#htmlからリンクを抜き出してくれる。
from bs4 import BeautifulSoup
#
from config import MONGO_URL
#DBに接続
client = MongoClient(MONGO_URL)
#urlparseでURLのパスだけ抜き出す。それでデータベースを取得
db = client[urlparse(MONGO_URL).path[1:]]
#存在するIndexというデータベースを取り出す。
col = db["Index"]
def _split_to_word(text):
"""Japanese morphological analysis with janome.
Splitting text and creating words list.
"""
t = Tokenizer()
#token.surfaceで日本語の文字列だけ取り出せる。
return [token.surface for token in t.tokenize(text)]
def _get_page(url):
r = requests.get(url)
if r.status_code == 200:
return r.text
def _extract_url_links(html):
"""extract url links
>>> _extract_url_links('aa<a href="link1">link1</a>bb<a href="link2">link2</a>cc')
['link1', 'link2']
"""
#"html.parser"はなるべくpython標準のparserモジュールを使うように指定しているBeautifulSoup()で
#BeautifulSoupで扱えるようにしている。
soup = BeautifulSoup(html, "html.parser")
return soup.find_all('a')
def add_to_index(keyword, url):
entry = col.find_one({'keyword': keyword})
if entry:
if url not in entry['url']:
entry['url'].append(url)
col.save(entry)
return
# not found, add new keyword to index
col.insert({'keyword': keyword, 'url': [url]})
def add_page_to_index(url, html):
body_soup = BeautifulSoup(html, "html.parser").find('body')
#htmlないの属性タグとその中身をchild_tagに入れていってる
for child_tag in body_soup.findChildren():
#beautifulsoupの機能でタグの名前だけ取り出してる
if child_tag.name == 'script':
continue
child_text = child_tag.text
for line in child_text.split('\n'):
line = line.rstrip().lstrip()
for word in _split_to_word(line):
add_to_index(word, url)
def crawl_web(seed, max_depth):
to_crawl = {seed}
crawled = []
next_depth = []
depth = 0
while to_crawl and depth <= max_depth:
#回収したurlの後ろを削除しpage_urlに入れる。
page_url = to_crawl.pop()
if page_url not in crawled:
html = _get_page(page_url)
add_page_to_index(page_url, html)
to_crawl = to_crawl.union(_extract_url_links(html))
crawled.append(page_url)
if not to_crawl:
to_crawl, next_depth = next_depth, []
depth += 1
新しいエラー2
データベースを確認したらURLは追加されていました。今度はそれを検索エンジンとしてクロームから見たいのですがcrawler.py(crawler.pyって深度設定がしてあるので読み込んだら勝手に止ままると思うのですが)を止めてからpython manage.py webpageを実行しlocalhost:9000にアクセスするのですが拒否されてしまいます。
pysearch-master/manage.py
# -*- coding: utf-8 -*-
import argparse
__author__ = 'c-bata'
if __name__ == '__main__':
#エラーの時にメッセージを表示する。
parser = argparse.ArgumentParser("Runner")
parser.add_argument('action', type=str, nargs=None, help="Select target 'crawler' or 'webpage'?")
args = parser.parse_args()
if args.action == 'crawler':
#コマンドラインでcrawlerって打ち込まれたらweb_crawlerって言うフォルダからcrawler.pyを読み込んでcrawl_webっていうdefを持ってくる
from web_crawler.crawler import crawl_web
crawl_web('http://docs.sphinx-users.jp/contents.html', 2)
elif args.action == 'webpage':
from search_engine import app
app.run(debug=True, port=9000)
else:
raise ValueError('Please select "crawler" or "webpage".')
pysearch-master/search_engine/__init__.py
from urllib.parse import urlparse
from flask import Flask, render_template, request
from pymongo import MongoClient
app = Flask(__name__)
app.config.from_object('config')
# DB settings
MONGO_URL = app.config['MONGO_URL']
client = MongoClient(MONGO_URL)
db = client[urlparse(MONGO_URL).path[1:]]
col = db["Index"]
@app.route('/', methods=['GET', 'POST'])
def index():
"""Return index.html
"""
if request.method == 'POST':
keyword = request.form['keyword']
if keyword:
return render_template(
'index.html',
query=col.find_one({'keyword': keyword}),
keyword=keyword)
return render_template('index.html')
netstatでというコマンドで確認したらLISTEN状態になっていたので起動は出来ていると思います。
tcp 0 0 localhost:9000 *:* LISTEN
pingは飛ばすことが出来ません。
実行 ping -c 1 127.0.0.1:9000/
ping: unknown host 127.0.0.1:9000/
Vagrantについて続きの質問があるのでページを新しくさせて頂きました。ご協力お願いします。
やっと環境構築出来てここまで来たらどうして動かしたいので詳しい方協力して頂けないでしょうか?