Выскабливание информации из библиотечного каталога - PullRequest
0 голосов
/ 20 мая 2018

Я работаю над проектом по сбору каталожной информации для книг из определенной библиотеки.Сценарий, который у меня есть, может очистить все ячейки таблицы.Однако я не совсем понимаю, как вернуть только определенные ячейки библиотеки Новой Британии.

import requests
from bs4 import BeautifulSoup

mypage = 'http://lci-mt.iii.com/iii/encore/record/C__Rb1872125__S%28*%29%20f%3Aa%20c%3A47__P0%2C3__Orightresult__U__X6?lang=eng&suite=cobalt'
response = requests.get(mypage)

soup = BeautifulSoup(response.text, 'html.parser')

data = []
table = soup.find('table', attrs={'class':'itemTable'})


rows = table.find_all('tr')
for row in rows:
    cols = row.find_all('td')
    cols = [ele.text.strip() for ele in cols]
    data.append([ele for ele in cols if ele]) # Get rid of empty values

for index, libraryinfo in enumerate(data):
    print(index, libraryinfo)

Вот пример вывода библиотеки Новой Британии из сценария:

["New Britain, Main Library - Children's Department", 'J FIC PALACIO', 'Check Shelf']

Вместо того, чтобы возвращать все ячейки, как мне вернуть только ячейки, относящиеся к библиотеке Новой Британии?Мне нужно только имя библиотеки и статус оформления заказа.

Желаемый результат будет:

["New Britain, Main Library - Children's Department", 'Check Shelf']

Может быть несколько ячеек, поскольку книга может иметь несколько копий вта же библиотека.

Ответы [ 3 ]

0 голосов
/ 20 мая 2018

Чтобы просто отфильтровать данные на основе определенного поля (первое в вашем примере), вы можете построить понимание:

[element for element in data if 'New Britain' in element[0]]

В приведенном вами примере исключены пустые значения, которые делают элементы данныхимеют разные размеры.Это затрудняет понимание того, какое поле соответствует каждому компоненту данных.Используя диктовки, мы можем сделать данные более понятными и удобными для обработки.

В некоторых полях, по-видимому, содержатся пустые куски (только с пробелами ['\n', '\r', * 1008)*, ' ']).Так что стриптиз не уберет.Объединение этого с простым регулярным выражением может помочь улучшить это.Я написал для этого простую функцию:

def squish(s):
    return re.sub(r'\s+', ' ', s)

Подводя итог, я думаю, это вам поможет:

import re

import requests
from bs4 import BeautifulSoup


def squish(s):
    return re.sub(r'\s+', ' ', s)


def filter_by_location(data, location_name):
    return [x for x in data if location_name.lower() in x['Location'].lower()]


mypage = 'http://lci-mt.iii.com/iii/encore/record/C__Rb1872125__S%28*%29%20f%3Aa%20c%3A47__P0%2C3__Orightresult__U__X6?lang=eng&suite=cobalt'
response = requests.get(mypage)

soup = BeautifulSoup(response.text, 'html.parser')

data = []
table = soup.find('table', attrs={'class':'itemTable'})

headers = [squish(element.text.strip()) for element in table.find('tr').find_all('th')]

for row in table.find_all('tr')[1:]:
    cols = [squish(element.text.strip()) for element in row.find_all('td')]
    data.append({k:v for k, v in zip(headers, cols)})

filtered_data = filter_by_location(data, 'New Britain')
for x in filtered_data:
    print('Location: {}'.format(x['Location']))
    print('Status: {}'.format(x['Status']))
    print()

Запустив его, я получил следующий результат:

Location: New Britain, Jefferson Branch - Children's Department
Status: Check Shelf

Location: New Britain, Main Library - Children's Department
Status: Check Shelf

Location: New Britain, Main Library - Children's Department
Status: Check Shelf
0 голосов
/ 20 мая 2018

Попробуйте получить желаемый контент:

import requests
from bs4 import BeautifulSoup

URL = "http://lci-mt.iii.com/iii/encore/record/C__Rb1872125__S%28*%29%20f%3Aa%20c%3A47__P0%2C3__Orightresult__U__X6?lang=eng&suite=cobalt"

res = requests.get(URL)
soup = BeautifulSoup(res.text,"lxml")
for items in soup.find("table",class_="itemTable").find_all("tr"):
    if "New Britain" in items.text:
        data = items.find_all("td")
        name = data[0].a.get_text(strip=True)
        status = data[2].get_text(strip=True)
        print(name,status)

Вывод:

New Britain, Jefferson Branch - Children's Department Check Shelf
New Britain, Main Library - Children's Department Check Shelf
New Britain, Main Library - Children's Department Check Shelf
0 голосов
/ 20 мая 2018

Фильтрация строк, не относящихся к Новой Британии, требует только проверки того, имеет ли первый элемент cols (то есть cols[0]) имя библиотеки.

Получение только имен библиотек истатус оформления заказа прост.Вам просто нужно получить доступ к первому и третьему элементам cols (то есть [cols[0], cols[2]]), так как они имеют имя библиотеки и статус проверки соответственно.

Вы можете попробовать заменить data.append([ele for ele in cols if ele]) на следующее.

# We gotta do this to skip empty rows.
if len(cols) == 0:
    continue

if 'New Britain' in cols[0]:
    data.append([cols[0], cols[2]])

Ваш код будет выглядеть следующим образом:

import requests
from bs4 import BeautifulSoup

mypage = 'http://lci-mt.iii.com/iii/encore/record/C__Rb1872125__S%28*%29%20f%3Aa%20c%3A47__P0%2C3__Orightresult__U__X6?lang=eng&suite=cobalt'
response = requests.get(mypage)

soup = BeautifulSoup(response.text, 'html.parser')

data = []
table = soup.find('table', attrs={'class':'itemTable'})

rows = table.find_all('tr')
for row in rows:
    cols = row.find_all('td')
    cols = [ele.text.strip() for ele in cols]

    if len(cols) == 0:
        continue

    if 'New Britain' in cols[0]:
        data.append([cols[0], cols[2]])

for index, libraryinfo in enumerate(data):
    print(index, libraryinfo)

Вывод:

0 ["New Britain, Jefferson Branch - Children's Department", 'Check Shelf']
1 ["New Britain, Main Library - Children's Department", 'Check Shelf']
2 ["New Britain, Main Library - Children's Department", 'Check Shelf']
...