Начал изучение python. Написал паука, который обходит страницы и записывает их в бд с глубиной 3. Я, конечно, понимаю, что он не распараллелен, и это долгий процесс + я несовсем верно сделал комиты в бд. Но он работает уже 7 часов, и прошел даже не половину страниц. Я думаю, что я где-то зациклил код.
crawler
import re
import bs4
import requests
from db import Db
from bs4 import BeautifulSoup
from urllib.parse import urlparse, urljoin
class Crawler:
def __init__(self, ignoreWords):
self.ignoreWords = ignoreWords
'''/*self.listSites = listSites
self.depth = depth
'''
self.Db = Db('myDB.db')
def crawl(self,sitesList,depth, morph):
tmpSitesList = []
counter = 0
file = open('word.txt', 'w')
file2 = open('link.txt', 'w')
file3 = open("urls.txt",'w')
i=0
while i != depth:
for site in sitesList:
counter += 1
sitesList.pop(0)
'''if i==0:
self.Db.addLink(site)'''
try:
#print("{}/{} {} Попытка открыть {} ...".format(counter, len(sitesList), site))
html_doc = requests.get(site).text # получить HTML код страницы
except Exception as e:
# обработка исключений при ошибке запроса содержимого страницы
print(e)
continue # перейти к следующему url
soup = bs4.BeautifulSoup(html_doc, "html.parser")
# шаг-4. Найти на странице блоки со скриптами и стилями оформления ('script', 'style')
listUnwantedItems = ['script', 'style']
for script in soup.find_all(listUnwantedItems):
script.decompose() # очистить содержимое элемента и удалить его из дерева
if (self.isIndexed(site) == True):
continue
self.addIndex(site,soup,morph)
print("Я обрабатал ссылку ")
aaaa = self.Db.returnIdUrl(site)
file3.write(str(aaaa[0]) + ' '+ str(aaaa[1]) + ' depth ' + str(depth) + '\n')
count = self.Db.countWord()
file.write(str(count[0]) + ' ' + str(counter) + '\n')
foundLinks = soup.find_all('a')
for link in foundLinks:
if 'href' in link.attrs:
linkUrl = link.attrs['href']
if linkUrl.startswith("http") and link != site:
if linkUrl != site and linkUrl !='/':
self.addLinkRef(site, linkUrl)
if linkUrl not in tmpSitesList and self.isIndexed(linkUrl) == False:
tmpSitesList.append(linkUrl)
else:
if linkUrl !='/':
linkUrl = link.attrs['href']
url = urljoin(site, linkUrl)
if url != site:
self.addLinkRef(site, url)
if linkUrl not in tmpSitesList and self.isIndexed(linkUrl) == False:
tmpSitesList.append(url)
countLink = self.Db.countLinkBetween()
file2.write(str(countLink[0]) + " " + str(counter)+ "\n")
if len(sitesList) == 0 :
sitesList = tmpSitesList.copy()
tmpSitesList.clear()
i=i+1
file.close()
file2.close()
file3.close()
def addIndex(self, url, soup,morph,ignoreWords = []):
if(self.isIndexed(url)):
return
#print(soup)
self.Db.addLink(url)
text = self.getTextOnly(soup)
words = self.separateWords(text)
print(words)
for id,word in enumerate(words):
p = morph.parse(word)[0]
if p.tag.POS != 'INTJ':
worded = self.getEntryId('worldList', 'word',word, True)
wordedLocation = self.Db.createIndexLocation(url,worded[0],id)
def getTextOnly(self, soup):
result = ''
#Получить все div
allDivs = soup.find_all('div')
#Получить весь текст из div
for div in allDivs:
result +=div.get_text()
return result.strip()
def separateWords(self, text):
wordsList = []
tmp = ''
text = re.sub("\xa0", " ", text)
for i in range(0,len(text)):
if text[i] != " " and text[i] !="\n" and text[i]!='':
tmp += text[i]
if text[i] == "\n" and text[i+1]!="\n" or text[i] == " ":
if text[i] != '' and tmp!='':
wordsList.append(tmp)
tmp = ''
return wordsList
def isIndexed(self,url):
return self.Db.isIndexed(url)
def addLinkRef(self,urlForm,urlTo):
self.Db.addLink(urlTo)
self.Db.addLinkBetween(urlForm,urlTo)
pass
def createIndexTables(self):
pass
def getEntryId(self, table,field,value,createNew):
return self.Db.getIndex(table, field, value, createNew)