2014-12-17 2 views
0

Я экспериментировал с веб-контентом в последнее время, используя 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() 

ответ

0

вы используете «DOWNLOAD_DELAY» в настройках гусеничном, установите задержку загрузки для изготовления паука быстрее, но убедитесь, что сайт позволяет, в противном случае может быть вы будете заблокированы на сайте источника очень скоро.

DOWNLOAD_DELAY = 0 //as much as it is possible 
Смежные вопросы