Форум сайта python.su
0
Здравствуйте.
Пишу парсер. Нужно сохранять результат в csv файл в виде:
вопрос;категория.
Создал словарь urls в функции main.
import requests from bs4 import BeautifulSoup import csv import re def get_html(url): r = requests.get(url) return r.text # Преобразуем строку в нижний регистр def cleaner(data): s = data.lower() return s def write_csv(data): with open('zonazakona.csv', 'a') as f: order = ['question', 'cat'] writer = csv.DictWriter(f, fieldnames=order, delimiter=';') writer.writerow(data) # Делаем предложения с большой буквы def uppercase(matchobj): return matchobj.group(0).upper() def capitalize(s): return re.sub('^([а-я])|[\.|\?|\!]\s*([а-я])|\s+([а-я])(?=\.)', uppercase, s) def main(): urls = {'https://www.zonazakona.ru/forum/forum/28-obschie-voprosy-po-zhilischnomu-pravu/': 'Жилищное право', 'https://www.zonazakona.ru/forum/forum/27-forum-po-semeynomu-pravu/': 'Семейное право'} for url in urls.keys(): while True: html = get_html(url) soup = BeautifulSoup(html, 'lxml') lis = soup.find('ol', class_='ipsDataList').find_all('li', class_='ipsDataItem') for li in lis: unclean_question = li.find('div', class_='ipsDataItem_main').find('span', class_='ipsType_break').find('a').text.strip() question = capitalize(cleaner(unclean_question)) cat = urls[url] data = {'question': question, 'cat': cat} # Если количество слов 4 и выше, то записываем вопрос в csv if len(question.split()) > 3: write_csv(data) try: url = soup.find('ul', class_='ipsPagination').find('li', class_='ipsPagination_next').find('a').get('href') except: break if __name__ == '__main__': main()
try: url = soup.find('ul', class_='ipsPagination').find('li', class_='ipsPagination_next').find('a').get('href') except: break
cat = urls[url]
Traceback (most recent call last):
File "/home/mjeday/Рабочий стол/python/zonazakona/main.py", line 72, in <module>
main()
File "/home/mjeday/Рабочий стол/python/zonazakona/main.py", line 58, in main
cat = urls[url]
KeyError: 'https://www.zonazakona.ru/forum/forum/28-obschie-voprosy-po-zhilischnomu-pravu/page/2/'
Отредактировано barbiturat (Сен. 22, 2019 01:08:05)
Офлайн
568
barbiturat
barbituratв этом блоке вы перехватываете ВСЕ исключения, ваш трейсбек не может быть из этого места.
try:
url = soup.find('ul', class_='ipsPagination').find('li', class_='ipsPagination_next').find('a').get('href')
except:
break
cat = urls[url]
for url in urls.keys():
url = soup.find('ul', class_='ipsPagination').find('li', class_='ipsPagination_next').find('a').get('href')Отредактировано FishHook (Сен. 22, 2019 01:41:24)
Офлайн
0
FishHook,
Я сначала беру url из словаря, чтобы спарсить первую страницу. А тут
url = soup.find('ul', class_='ipsPagination').find('li', class_='ipsPagination_next').find('a').get('href')
Отредактировано barbiturat (Сен. 22, 2019 16:22:30)
Офлайн
0
Сам спросил, сам ответил
Так надо:
def main(): urls = {'https://www.zonazakona.ru/forum/forum/28-obschie-voprosy-po-zhilischnomu-pravu/': 'Жилищное право', 'https://www.zonazakona.ru/forum/forum/27-forum-po-semeynomu-pravu/': 'Семейное право'} for url in urls.keys(): cat = urls[url] while True: html = get_html(url) soup = BeautifulSoup(html, 'lxml') lis = soup.find('ol', class_='ipsDataList').find_all('li', class_='ipsDataItem') for li in lis: unclean_question = li.find('div', class_='ipsDataItem_main').find('span', class_='ipsType_break').find('a').text.strip() question = capitalize(cleaner(unclean_question)) data = {'question': question, 'cat': cat} # Если количество слов 4 и выше, то записываем вопрос в csv if len(question.split()) > 3: write_csv(data) try: url = soup.find('ul', class_='ipsPagination').find('li', class_='ipsPagination_next').find('a').get('href') except: break
Офлайн
0
В общем, теперь все работает.
def main(): urls = {'https://www.zonazakona.ru/forum/forum/28-obschie-voprosy-po-zhilischnomu-pravu/': 'Жилищное право', 'https://www.zonazakona.ru/forum/forum/27-forum-po-semeynomu-pravu/': 'Семейное право'} for url in urls.keys(): cat = urls[url] while True: html = get_html(url) soup = BeautifulSoup(html, 'lxml') lis = soup.find('ol', class_='ipsDataList').find_all('li', class_='ipsDataItem') for li in lis: unclean_question = li.find('div', class_='ipsDataItem_main').find('span', class_='ipsType_break').find('a').text.strip() question = capitalize(cleaner(unclean_question)) data = {'question': question, 'cat': cat} # Если количество слов 4 и выше, то записываем вопрос в csv if len(question.split()) > 3: write_csv(data) # Проверяем, есть ли ссылка "Вперёд" pattern = soup.find('ul', class_='ipsPagination').find('li', class_='ipsPagination_next').get('class') s_pattern = ' '.join(pattern) # Преобразуем список в строку if s_pattern == 'ipsPagination_next ipsPagination_inactive': break url = soup.find('ul', class_='ipsPagination').find('li', class_='ipsPagination_next').find('a').get('href')
{'url': 'cat': '1', 'url2': 'cat2': '2', 'url3': 'cat3': '3',}
Отредактировано barbiturat (Сен. 22, 2019 17:53:04)
Офлайн