Я пытаюсь заставить этого паука просмотреть список из 1600 URL-адресов, содержащихся в CSV-файле, и извлечь со страницы адреса электронной почты и номера телефонов. Если у кого-нибудь уже есть такая программа, я был бы рад ее использовать, но также мне хотелось бы знать, где я ошибся. Вот мой код, я передал его через чат gpt, чтобы уточнить и аннотировать.
импортировать Scrapy импортировать панд как pd импортировать ОС импортировать повторно журнал импорта класс Паук(scrapy.Spider): имя = 'business_scrape' защита Extract_emails (я, текст): # Извлекаем адреса электронной почты, используя комплексный шаблон регулярного выражения электронная почта = re.findall( r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', текст) возвращать электронные письма защита Extract_phone (я, текст): # Извлекаем номера телефонов phone_numbers = re.findall( r'(?:(?:\+\d{1,2}\s?)?\(?\d{3}\)?[-.\s]?)?\d{3,4}[ -.\s]?\d{4}', текст) вернуть номера_телефонов защита start_requests (сам): # Прочитайте исходный файл CSV со столбцами [имя, URL, категория] csv = 'bozeman_businesses.csv' # Укажите свой CSV-файл init_df = pd.read_csv(csv) для _ введите строку в init_df.iterrows(): имя = строка['имя'] URL = строка['url'] категория = строка['категория'] выход Scrapy.Request (url = URL, callback = self.parse_link, мета = {'name': имя, 'категория': категория}) def parse_link(сам, ответ): имя = ответ.мета['имя'] категория = response.meta['категория'] # Инициализируем ведение журнала logging.basicConfig( filename='scrapy.log', format='%(levelname)s: %(message)s', level=logging.INFO) # Зафиксировать начало сканирования logging.info('Сканирование началось.') для слова в self.reject: если слово в str(response.url): возвращаться html_text = str(response.text) пытаться: # Извлеките адреса электронной почты с помощью функции mail_list = self.extract_emails(html_text) # Извлекаем номера телефонов с помощью функции phone_numbers = self.extract_phone(html_text) # Убедитесь, что списки «электронная почта» и «телефон» имеют одинаковую длину min_length = min(len(mail_list), len(phone_numbers)) список_почты = список_почты[:min_length] номер_телефона = номер_телефона[:min_length] dic = {'name': [имя], 'категория': [категория], 'электронная почта': mail_list, 'телефон': phone_numbers, 'url': [str(response.url)]} кроме исключения как e: # Обработайте сбой, установив значения «NA» self.logger.error(f'Ошибка очистки {response.url}: {e}') dic = {'name': [имя], 'категория': [категория], 'электронная почта': ['NA'], 'phone': ['NA'], 'url': [str(response.url)]} # Проверяем, существует ли выходной файл, и сообщаем пользователю, существует ли он если os.path.exists(self.path): ответ = self.ask_user('Файл уже существует, заменить?') если ответ ложный: возвращаться # Создать или перезаписать выходной файл self.create_or_overwrite_file(self.path) # Добавляем данные в выходной CSV-файл df = pd.DataFrame(dic) df.to_csv(self.path, mode='a', header=False, index=False) # Определите список отклонения и путь к выходному файлу ignore = ['example.com', 'example2.com'] # Отрегулируйте по мере необходимости path = 'output.csv' # При необходимости измените путь к выходному файлу def Ask_user(я, вопрос): ответ = ввод (вопрос + 'y/n' + '\n') вернуть ответ.lower() == 'y' Защиту create_or_overwrite_file(self, путь): ответ = Ложь если os.path.exists(путь): ответ = self.ask_user('Файл уже существует, заменить?') если ответ ложный: возвращаться с open(path, 'wb') как файлом: файл.закрыть() Мой журнал довольно длинный, поэтому вот несколько выдержек:
21.09.2023 15:51:02 [scrapy.core.engine] ОТЛАДКА: просканировано (200) (ссылка: нет) 2023-09-21 15:51:02 [scrapy.spidermiddlewares.httperror] ИНФОРМАЦИЯ: игнорирование ответа : код состояния HTTP не обрабатывается или не разрешен 2023-09-21 15:51:03 [scrapy.downloadermiddlewares.redirect] ОТЛАДКА: перенаправление (308) на с 2023-09-21 15:51:03 [scrapy.downloadermiddlewares.redirect] ОТЛАДКА: перенаправление (301) на с 2023-09-21 15:51:03 [scrapy.downloadermiddlewares.redirect] ОТЛАДКА: перенаправление (301) на из 2023-09-21 15:51:03 [scrapy.core.engine] ОТЛАДКА: просканировано (200) (референт: нет) 2023-09-21 15:51:03 [root] ИНФО: Началось сканирование. Пока всё хорошо
файл "/Users/me/opt/anaconda3/lib/python3.9/site-packages/pandas/core/internals/construction.py", строка 502, в dict_to_mgr return arrays_to_mgr(массивы, столбцы, индекс, dtype=dtype, typ=typ, консолидация=копировать) Файл «/Users/me/opt/anaconda3/lib/python3.9/site-packages/pandas/core/internals/construction.py», строка 120, в arrays_to_mgr индекс = _extract_index(массивы) Файл «/Users/me/opt/anaconda3/lib/python3.9/site-packages/pandas/core/internals/construction.py», строка 674, в _extract_index поднять ValueError("Все массивы должны быть одинаковой длины" Мне кажется, что проблема в ошибке в длине массива. Я попытался добавить значения NA, если процесс не удался. Кажется, не помогло

Эта ошибка тоже всплывала.
21.09.2023, 15:52:03 [scrapy.downloadermiddlewares.retry] ОШИБКА: прекращена повторная попытка (3 раза не удалось): [] 2023-09-21 15:52:03 [scrapy.downloadermiddlewares.robotstxt] ОШИБКА: Ошибка загрузки : [] Остальная часть журнала по сути повторяется.
Что я сделал и чего ожидал:
[*]Я попробовал добавить попытку, за исключением циклов, позволяющих пропускать проблемные сайты и вводить значения NA. [*]Я ожидал, что даже если я не смогу получить нужную информацию, у меня все равно будет CSV-файл с названием компании, URL-адресом и значениями NA. [*]Мне также было бы интересно узнать, как мне лучше отладить это самостоятельно.