Оптимизация кода парсера

Я практикуюсь в написании парсеров. Пытаюсь написать как можно оптимальнее. Можно ли его как-нибудь оптимизировать?

Вот мой код, главная идея это собрать ссылки на изображения и тэги. С сайта reactor.cc.

Код рабочий, но мне кажется в плане оптимизации он ужасен, прошу посмотреть и сказать что можно изменить. У меня мысли насчет не практичности моего использования try. Говорят использовать это в цикле - табу, как goto в с++.


import logging
import requests
from bs4 import BeautifulSoup


def get_content():
    tags = None
    image = None
    content = requests.get('http://joyreactor.cc/')
    soup = BeautifulSoup(content.text, 'lxml')
    posts = soup.find_all('div', class_='postContainer')
    data = []
    for post in posts:
        try:
            image = post.find('div', class_='image').find('img')['src']
            tags = post.find('h2', class_='taglist').find_all('b')
        except AttributeError:
            print(post)
            continue
        except Exception as e:
            logging.exception(e)
        row = str(len(tags)).split()
        for tag in tags:
            tag = tag.find('a')['title']
            row.append(tag)
        row[0] = image
        data.append(row)
    print(data)


get_content()


Ответы (2 шт):

Автор решения: ganz

Как то так...

import logging
import requests
from bs4 import BeautifulSoup


def get_content():
    #атавизм из строго типизированых яп?
    tags = None
    image = None
    content = requests.get('http://joyreactor.cc/')
    soup = BeautifulSoup(content.text, 'lxml')

    #здесь можно удалить переменную content, на случай если вдруг когда либо нужно будет парсить ну прям очень много данных
    del content
    
    posts = soup.find_all('div', class_='postContainer')
    data = []

    for post in posts: #тут тоже можно удалять обработанные значения, но это уложнит понимание кода
        #try тут нежелательно так как можно проверить наличие атрибута через if
        try:
            image = post.find('div', class_='image').find('img')['src']
            tags = post.find('h2', class_='taglist').find_all('b')
        except AttributeError:
            print(post)
            continue
        except Exception as e: #а это выражение довольно часто вводит в заблуждение
            logging.exception(e) #но хотябы логируются

        row = str(len(tags)).split()
        for tag in tags: #есть предположение что лямбда работала бы быстрее но выглядела бы хуже
            tag = tag.find('a')['title']
            row.append(tag)
        row[0] = image
        data.append(row)
    print(row)


get_content()
→ Ссылка
Автор решения: Сергей Шашко

По коду

import logging
import requests
from bs4 import BeautifulSoup


def get_content():
    tags = None
    image = None
    content = requests.get('http://joyreactor.cc/')
    soup = BeautifulSoup(content.text, 'lxml')
    posts = soup.find_all('div', class_='postContainer')
    data = []
    for post in posts:
        try:
            image = post.find('div', class_='image').find('img')['src']
            tags=post.find('h2',class_='taglist').find_all('a')
'''
find_all('b') заменяем find_all('a')
 в выбраном теге 'h2' остались все нам нужные теги 'a'
''' 
        except AttributeError:
            print(post)
            continue
        except Exception as e:
            logging.exception(e)
        row = [image]  
'''
row = str(len(tags)).split() Добротный костыль )) на пару row[0] = image
'''
        for tag in tags:
'''
tag = tag.find('a')['title']
в теге 'a' остался текст в количестве одна штука извлекаем его tag.text
'''
            row.append(tag.text)
'''
row[0] = image
коммент выше
'''
        data.append(row)
    print(data)


get_content()

Код сыроват:

  1. Не извлекает ссылки на gif-ки
  2. В не которых постах есть несколько картинок. Извлекается только одна ссылка на картинку.
    Моя оптимизация Мутим генератор списка
tags =[tag.text for tag in post.find('h2', class_='taglist').find_all('a')]
print(tags)
['cosplay', 'Millenia69', 'Melisandre', 'ИП others', 'Игра престолов', 'фэндомы', 'ИП косплей', 'под катом еще']  

Потребность в цикле for tag in tags отпадает

data.append(image,tags) 

Правда на выходе формат чуть чуть другой. Ну и да ладно, я художник, я так вижу.))

P.S. "Я не волшебник, я только учусь" (х/ф"Золушка"(1947))

→ Ссылка