Я думаю, что основная причина, по которой ваш код застревает, заключается в том, что некоторые веб-страницы ссылаются на страницу, которую ваш код уже посещал; это создает бесконечный цикл с нависшим рекурсивным вызовом.
Чтобы этого избежать, нужно отслеживать посещенные ссылки; Вы можете сделать это с помощью списка, как я сделал в коде ниже.
Приведенный ниже код достигает конца поиска, но для этого есть несколько предостережений, о которых нужно позаботиться:
некоторые страницы ссылаются на внешние ссылки, которые не работают; поэтому я поставил предложение try, except
(иначе: ошибки ...)
некоторый текст (по крайней мере, один, насколько я мог проверить) содержит специальный символ - '\ u200b' - который раздражает запись в файл, поэтому я изменил open на codecs.open с кодировкой, чтобы уметь управлять им.
По крайней мере одна ссылка перенаправляет на https://web.archive.org/... (см. Код ниже), поэтому я использовал регулярное выражение, чтобы вернуть его на www.thebalancecareers.com/. Если это не то, что вы собираетесь делать с этими ссылками, вам нужно адаптировать код.
Наконец, я прокомментировал последний writeToFile(ul)
, поскольку он записывал None в файл, вызывая ошибки.
Надеюсь, это поможет.
import urllib
import urllib.request
from bs4 import BeautifulSoup
import codecs
import re
def writeToFile(ul):
for li in ul:
# codecs.open with encoding can manage some spacial characters in
# you text such as '\u200b'
with codecs.open('file.txt', encoding='utf-8', mode='a+') as f:
text = li.text
f.write(text + ',')
f.close()
def searchElements(url, visitedurls):
visitedurls.append(url)
print(url)
# Uncomment the following line to see all link visited by searchElements
# print(visitedurls)
# Some external links referenced by www.thebalancecareers.com
# don't exist anymore or are forbidden
try:
response = urllib.request.urlopen(url)
except (urllib.error.HTTPError, urllib.error.URLError):
return
html = response.read()
soup = BeautifulSoup(html, 'html.parser')
divs = soup.findAll('div', id=lambda x: x and x.startswith('mntl-sc-block_1-0-'))
for div in divs:
ul = div.find("ul")
if ul is not None:
ulVariable = ul.findAll('a')
for b in ulVariable:
if ulVariable is not None:
if b is not None:
linkItemsList = list()
links = (b.get("href"))
linkItemsList.append(links)
for link in linkItemsList:
# Get rid of this kind of link:
# https://web.archive.org/web/20180425012458/https:/www.thebalancecareers.com/....
link = re.sub(r'https://web.archive.org/(.*)/https:', 'https:/', link)
if link in visitedurls:
print('%s already traversed' % link)
return
else:
searchElements(link, visitedurls)
print('link internal data print')
writeToFile(ul)
else:
print('link in not none else')
writeToFile(ul)
print('all non link')
# Commented: this would try to write None
# resulting in an error
#writeToFile(ul)
def main():
visitedurls = []
searchElements('https://www.thebalancecareers.com/list-of-information-technology-it-skills-2062410', visitedurls)
if __name__ == '__main__':
main()