Веб-соскабливание списка юристов

Я написал программу, чтобы получить имена вместе с названиями некоторых практикующих из веб-страница . Содержимое, хранящееся в неорганизованных элементах HTML (по крайней мере, мне показалось), и, как результат, результат становится беспорядочным. Тем не менее, мне удалось получить результат как и должно быть.

То, как я написал скребок, отлично подходит для его цели, но сам скребок выглядит уродливым. Есть ли способ сделать скребок хорошо выглядеть и все еще выполнять ту же работу, что и сейчас? Например, существует ли способ устранения обработчиков исключений?

Вот как я это написал:

import requests 
from bs4 import BeautifulSoup

url = "https://www.otla.com/index.cfm?&m_firstname=a&seed=566485&fs_match=s&pg=publicdirectory&diraction=SearchResults&memPageNum=1"

def get_names(link):
    res = requests.get(link)
    soup = BeautifulSoup(res.text,'lxml')
    for content in soup.select(".row-fluid"):
        try:
            name = content.select_one(".span5 b").get_text(strip=True)
        except: continue  #let go of blank elements
        else: name

        try:
            title = content.select_one(".span5 b").next_sibling.next_sibling.strip()
        except: continue  #let go of blank elements
        else: title

        print(name,title)

if __name__ == '__main__':
    get_names(url)
11 голосов | спросил Topto 31 Maypm18 2018, 23:47:29

3 ответа


7

Как уже обсуждалось @scnerd, избегая использования оголенного предложения try/except, я сосредоточусь на том, чтобы полностью удалить его.

После проверки источника веб-сайта вы заметите, что элементы класса row-fluid являются контейнерами для каждого адвоката. В каждом из этих элементов есть два элемента .span5 clearfix, один из которых содержит имя и фирму адвоката, а также их специализацию. Поскольку вы, кажется, не заинтересованы в последнем, мы можем полностью пропустить этот элемент и перейти к следующему.

for element in soup.select(".span5 b"):
    name = element.text.strip()
    if name.startswith('Area'):
        continue
    title = element.next_sibling.next_sibling.strip()
    print('{}: {}'.format(name, title))

Вы заметите, что я ушел из контейнера row-fluid из селектора, так как мы итерируем только по span5, которые содержатся в них, однако, если вы хотите сохранить это, вы можете связать селектор CSS как таковой: soup.select(".row-fluid .span5 b"). Если были какие-либо элементы класса span5 вне row-fluid, было бы лучше связать CSS, сделав его более явным.

get_names - это довольно неоднозначное имя функции, которое также предполагает, что оно вернет итерабельность с именами. То, что вы делаете в этой функции, - это печать имен юристов вместе с фирмой, в которой они работают. Я бы предложил переименовать его в print_lawyer_information или еще лучше get_lawyer_information и верните словарь, содержащий ключ name и title как значение.

lawyer_information = {}
for element in soup.select(".span5 b"):
    name = element.text.strip()
    if name.startswith('Area'):
        continue
    title = element.next_sibling.next_sibling.strip()
    lawyer_information[name] = title
return lawyer_information

Как вы можете видеть выше, мы создаем пустой словарь, а затем, когда мы перебираем элементы, мы добавляем записи к нему. Как только это будет сделано, вы просто вернете словарь, который затем вы можете распечатать или сделать больше. Это можно сделать с гораздо более аккуратным пониманием словаря.

return {row.text.strip(): row.next_sibling.next_sibling.strip()
        for row in soup.select('.span5 b')
        if not row.text.strip().startswith('Area')}

Пара других nitpicks будет включать в себя PEP-8 (руководство по стилю Python) нарушения, такие как отсутствие двух строк перед определением функции и несколько операторов в одной строке. Запустите свой код с помощью http://pep8online.com , и вы получите лучшее представление о том, как сделать свой код легче читать и следовать. Вы будете благодарны вам через несколько лет, когда вы снова посмотрите на свой код.

import requests
from bs4 import BeautifulSoup


def get_lawyer_information(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'lxml')
    return {element.text.strip(): element.next_sibling.next_sibling.strip()
            for element in soup.select('.span5 b')
            if not element.text.strip().startswith('Area')}


if __name__ == '__main__':
    url = "https://www.otla.com/index.cfm?&m_firstname=a&seed=566485&fs_match=s&pg=publicdirectory&diraction=SearchResults&memPageNum=1"
    lawyer_information = get_lawyer_information(url)
    for name, title in lawyer_information.items():
        print('{} | {}'.format(name, title))
ответил Lukasz Salitra 1 J0000006Europe/Moscow 2018, 04:07:25
7

Не используйте инструкцию except, если она не абсолютно необходимо. Поймайте ошибки, которые вы ожидаете и явно хотите обрабатывать.

Кроме того, нет никаких причин для дублированных операторов try/except/else и в этом случае использовать else. Вы можете свернуть все в один try/except, так как вы делаете то же самое, независимо от того, какая строка выдает ошибку.

У вас также есть небольшое дублирование кода. Не повторяйте себя (DRY).

def get_names(link):
    res = requests.get(link)
    soup = BeautifulSoup(res.text,'lxml')
    for content in soup.select(".row-fluid"):
        try:
            element = content.select_one(".span5 b")
            name = element.get_text(strip=True)
            title = element.next_sibling.next_sibling.strip()
            print(name,title)
        except AttributeError:
            continue
ответил scnerd 1 J0000006Europe/Moscow 2018, 00:19:42
3

Почему бы вам не поместить все тело цикла while внутри блока try? И вы можете просто отказаться от предложения else.

for content in soup.select(".row-fluid"):
    try:
        name = content.select_one(".span5 b").get_text(strip=True)
        title = content.select_one(".span5 b").next_sibling.next_sibling.strip()
        print(name,title)
    except: continue  #let go of blank elements
ответил Segfault 1 J0000006Europe/Moscow 2018, 00:18:42

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132