Я экспериментировал с веб-контентом в последнее время, используя python. Мне удалось предоставить поисковому роботу семя, из которого он начинает царапать заголовок каждого сайта, содержимое тела и каждую ссылку, ведущую на другую страницу.эффективно очищаем веб-сайт с помощью python
Прямо сейчас он гарантирует, что каждая ссылка уникальна, она вставляется в БД. Это делает его ужасно медленным, но это обязательная функция, я полагаю. Нет смысла иметь сотни дубликатов.
Я хочу знать, должен ли соскабливание страницы за 100 секунд, должно быть, это медленный процесс, и если да, то как я мог бы сделать это быстрее. Меня действительно интересует теория, стоящая за ней.
Кроме того, я предоставлю свой код на случай, если кто-то заинтересован в более глубоком изучении его.
import requests as req
from pymongo import MongoClient
from bs4 import BeautifulSoup
import re
from time import time
from urllib.parse import urlsplit
client = MongoClient("ds055980.mongolab.com", 55980)
db = client.crawler
db.authenticate("swenn", "password")
global duplicates, new_links
duplicates, new_links = 0, 0
time_list = []
def get_data(soup):
for script in soup(["script", "style"]):
script.extract()
if soup.title == None:
return False
else:
title = soup.title.string
content = soup.getText(separator=u' ')
if len(content) < 15:
return False
content = content.replace("\n", "")
title = title.replace("\n", "")
rge = re.compile(r'\s+')
content = rge.sub(" ", content)
return content, title
def insert_data_into_db(soup, url):
data = get_data(soup)
if data == False:
db.links.remove({"_id": url[0]})
db.blacklist.insert({"address": url[1]})
return False
db.data.insert({"address": url[1], "title": data[1], "content": data[0], "time": round(time()), "in_use": 0})
def insert_urls_into_db(soup, current_url):
global duplicates, new_links
new_links = 0
regex = re.compile(r'#.+')
link_list = list(set(soup.find_all('a', href = re.compile('.+'))))
for link in link_list:
url = link.get('href')
if "{" in url or "}" in url or "javascript:" in url or "mailto:" in url or url == "#" or url == "":
continue
if "://" in url:
pass
elif "//" == url[0::2]:
url = "http:" + url
else:
parsed_current = urlsplit(current_url[1])
if "/" in url[0]:
url = parsed_current.scheme+"://"+parsed_current.netloc+url
elif "?" in url[0]:
url = parsed_current.scheme+"://"+parsed_current.netloc+parsed_current.path+url
else:
url_sub = current_url[1][::-1]
url = url_sub[url_sub.index("/")::][::-1] + url
if "#" in url:
url = regex.sub("", url)
if db.links.find({"address": url}).count() == 0:
db.links.insert({"address": url, "time": 1, "in_use": 0})
new_links += 1
else:
duplicates += 1
db.links.update({"_id": current_url[0]}, {"$set": {"in_use": 0, "time": round(time())}})
def save_state_and_exit(urls):
print("Saving document state...")
for url in urls:
db.links.update({"_id": url[0]}, {"$set": {"in_use": 0, "time": 1}})
db.data.remove({"address": url[1]})
print("Exiting...")
exit()
def main():
while True:
urls = []
try:
documents = db.links.find({"time": {"$lt": round(time()) - 2592000}, "in_use": 0}).limit(10)
if documents == None:
print("Query did not match any documents. Exiting...")
break
for document in documents:
db.links.update({"_id": document["_id"]}, {"$set": {"in_use": 1}})
urls.append((document["_id"], document["address"]))
t = round(time())
for url in urls:
print("current URL:", url[1])
try:
html = req.get(url[1], timeout=5)
if html.encoding != 'utf-8':
html.encoding = 'utf-8'
html = html.text
except (req.exceptions.Timeout, req.exceptions.ConnectionError):
print("URL",url,"doesn\'t respond. Deleting...")
db.links.remove({"_id": url[0]})
if db.blacklist.find({"address": url[1]}).count() == 0:
db.blacklist.insert({"address": url[1]})
continue
soup = BeautifulSoup(html)
if insert_data_into_db(soup, url) == False:
continue
insert_urls_into_db(soup, url)
print("vottis aega:", round(time()) - t,"sekundit","\t","uusi linke:","\t","duplikaate:", duplicates,"\n\n")
except (KeyboardInterrupt, SystemExit):
save_state_and_exit(urls)
if __name__ == "__main__":
main()