0
나는 최근에 파이썬을 사용하여 웹 컨텐츠를 긁어 모으는 실험을 해왔다. 나는 크롤러에게 각 웹 사이트의 제목, 본문 내용 및 다른 페이지로 연결되는 모든 링크를 다듬기 시작하는 씨앗을 제공 할 수있었습니다.파이썬으로 효율적으로 웹을 긁어 냄
지금은 모든 링크가 DB에 삽입되는 고유 한 링크인지 확인합니다. 이것은 속도가 느려지지만 필연적 인 기능입니다. 수백 개의 복제본을 가지고 있다는 점은 없습니다.
~ 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()