Мой скрипт не выполняет поиск по всем ссылкам, что делать? - PullRequest
0 голосов
/ 10 июля 2020

Я создаю сценарий для сканирования веб-сайта, захвата URL-адресов и проверки, работает он или нет. Проблема в том, что сценарий ищет только URL-адреса домашней страницы веб-сайта и оставляет в стороне другие. Как мне захватить все страницы, связанные с сайтом?

Ниже моего приложения с кодом:

import urllib
from bs4 import BeautifulSoup
import re
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError


page = urllib.request.urlopen("http://www.google.com/")
soup = BeautifulSoup(page.read(), features='lxml')
links = soup.findAll("a", attrs={'href': re.compile('^(http://)')})
for link in links:

    result = (link["href"])

    req = Request(result)

    try:
        response = urlopen(req)
        pass

    except HTTPError as e:

        if e.code != 200:
            # Stop, Error!
            with open("Document_ERROR.txt", 'a') as archive:
               archive.write(result)
               archive.write('\n')
               archive.write('{} \n'.format(e.reason))
               archive.write('{}'.format(e.code))
               archive.close()
        
        else:
        # Enjoy!
            with open("Document_OK.txt", 'a') as archive:
               archive.write(result)
               archive.write('\n')
               archive.close()

1 Ответ

0 голосов
/ 11 июля 2020

Основная причина, по которой это не работает, заключается в том, что вы помещаете записи OK и ERROR внутри блока except.

Это означает, что будут сохранены только URL-адреса, которые действительно вызывают исключение.

В общем, я бы посоветовал вам распылить некоторые операторы печати на разных этапах сценария - или использовать IDE, которая позволяет вам выполнять код во время выполнения - построчно. Это значительно упрощает отладку подобных вещей.

PyCharm бесплатен и позволяет вам это делать. Попробуйте.

Итак - я не работал с urllib, но часто использую запросы (python -m pip install requests). Быстрый рефакторинг с использованием этого будет выглядеть примерно так:

import requests
from bs4 import BeautifulSoup 
import re

url = "http://www.google.com"
r = requests.get(url)
html = r.text
soup = BeautifulSoup(html, "lxml")

links = soup.find_all("a", attrs={'href': re.compile('^(http://)')}) 

for link in links: 
    href = link["href"]
    print("Testing for URL {}".format(href))
    
    try:
        # since you only want to scan for status code, no need to pull the entire html of the site - use HEAD instead of GET
        r = requests.head(href)
        status = r.status_code
        # 404 etc will not yield an error
        error = None
    except Exception as e:
        # these exception will not have a status_code
        status = None
        error = e
    
    # store the finding in your files
    if status is None or status != 200:
        print("URL is broken. Writing to ERROR_Doc")
        # do your storing here of href, status and error
    else:
        print("URL is live. Writing to OK_Doc"
        # do your storing here

Надеюсь, это имеет смысл.

...