Вэб-скраппинг страницы

asmadeus

Новичок
Пользователь
Июл 27, 2020
17
1
3
Доброго времени суток всем!
Я с Питоном два дня, до этого был на другом языке (ну с общими для всех языков принципами программирования знаком)
Не могу сладить с задачей - пока надо получить ссылку с ячейки таблицы, ссылка содержит дату "1995", но сама ссылка записана не как "a href=...", а как "data-href=..."
Код пока такой:
Код:
from urllib.parse import urlparse
import requests
from bs4 import BeautifulSoup
import lxml
import re

# Переменные
headers = {
    'accept': '*/*',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0',
    'Upgrade-Insecure-Requests': '1'
}

search = 'украина 1 гривна 1995'
yahr = re.search (r'\d{4}', search)
def ucoin():
    domain = 'ru.ucoin.net'
    host = 'http://' + domain
    url =( host + '/catalog/?' )
    session = requests.Session()
    request = session.get(url, headers=headers, params=[('q', search)])
    soup = BeautifulSoup(request.content, 'lxml')
    link = soup.find('table', {'class': 'coin'}).find('a').get('href')
    request = session.get(host + link, headers=headers)
    soup = BeautifulSoup(request.content, 'lxml')
    link = soup.find('tr', {"class" : "tr-hr"}, string=re.compile('1995'))
    print (link)


ucoin()

Вот как совладать с этой строкой:
link = soup.find('tr', {"class" : "tr-hr"}, string=re.compile('1995'))
Прошу помочь понять, на вопросы отвечу
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
надо получить ссылку с ячейки таблицы, ссылка содержит дату "1995"
Вот пример:
Python:
import requests
from bs4 import BeautifulSoup
import re

# Переменные
headers = {
    'accept': '*/*',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0',
    'Upgrade-Insecure-Requests': '1'
}

search = 'украина 1 гривна 1995'
yahr = re.search(r'\d{4}', search)


def ucoin():
    domain = 'ru.ucoin.net'
    host = 'http://' + domain
    url = host + '/catalog/?'
    session = requests.Session()
    request = session.get(url, headers=headers, params=[('q', search)])
    soup = BeautifulSoup(request.content, 'lxml')
    link = soup.find('table', {'class': 'coin'}).find('a').get('href')
    request = session.get(host + link, headers=headers)
    soup = BeautifulSoup(request.content, 'lxml')
    table = soup.find_all('tr', {"class": "tr-hr"})

    link = ''
    for s in table:
        if '1995' in s['data-href']:
            link = host + s['data-href']
    print(link)


ucoin()
 
  • Мне нравится
Реакции: asmadeus

asmadeus

Новичок
Пользователь
Июл 27, 2020
17
1
3
Да, непонятно как, но работает.
Поясните, что за "s" в строке
Python:
for s in table:
        if '1995' in s['data-href']:
            link = host + s['data-href']
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Да, непонятно как, но работает.
Поясните, что за "s" в строке
Python:
for s in table:
        if '1995' in s['data-href']:
            link = host + s['data-href']
table это список, а не строка. s - элемент списка.
 

asmadeus

Новичок
Пользователь
Июл 27, 2020
17
1
3
В ходе продолжения написания и проверок выяснилось, что ссылка может быть получена и ранее, а дальнейший код приводит к ошибке
Вот этот код становится лишним, когда есть только один единственный год (тогда второй анализ не выдает результата, так как нет таблицы):
Python:
request = session.get(host + link, headers=headers)
    soup = BeautifulSoup(request.content, 'lxml')
    table = soup.find_all('tr', {"class": "tr-hr"})

    link = ''
    for s in table:
        if '1995' in s['data-href']:
            link = host + s['data-href']
    print(link)
То есть ссылка получена строкой ранее :
Python:
link = soup.find('table', {'class': 'coin'}).find('a').get('href')
Надо, наверное проверять наличие самой таблицы ? Типа - существует таблица, идем далее. Не существует - используем уже полученную ссылку
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
код становится лишним, когда есть только один единственный год (тогда второй анализ не выдает результата, так как нет таблицы):
Надо, наверное проверять наличие самой таблицы ? Типа - существует таблица, идем далее. Не существует - используем уже полученную ссылку
Пример ссылки на которой код выдает ошибку покажите.
Проверку можно сделать простым условием if/else:
Python:
if table:
    # выполняем код дальше
else:
    print(link)
 

asmadeus

Новичок
Пользователь
Июл 27, 2020
17
1
3
Написал функцию так, насколько верно - сказать не могу, но ошибки пока не выдает:
Python:
    def ucoin():
        domain = 'ru.ucoin.net'
        host = 'https://' + domain
        url = (host + '/catalog/?')
        session = requests.Session()
        request = session.get(url, headers=headers, params=[('q', search)])
        soup = BeautifulSoup(request.content, 'lxml')
        link = soup.find('table', {'class': 'coin'}).find('a').get('href')
        request = session.get(host + link, headers=headers)
        soup = BeautifulSoup(request.content, 'lxml')
        table = soup.find_all('tr', {"class": "tr-hr"})
        if table:
            link = ''
            for s in table:
                if yahr.group(0) in s['data-href']:
                    link = host + s['data-href']
        else:
            link = host + link
        return link
 

asmadeus

Новичок
Пользователь
Июл 27, 2020
17
1
3
Доброго времени суток!
Продолжу здесь, так как скрипт тот же, отметки для установки темы решенной нет, так что и плодить новые пока не вижу смысла.
Задача примерно та же, что и ранее - парсинг, только другого сайта.
Мой код (урывочно):
Python:
import requests
from bs4 import BeautifulSoup
import lxml
import re

headers = {
    'accept': '*/*',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0',
    'Upgrade-Insecure-Requests': '1'
}

def numista():
    domain = 'en.numista.com'
    host = 'https://' + domain
    url = (host + '/catalogue/index.php?')
    session = requests.Session()
    request = session.get(url, headers=headers,
    params=[('q', 'Ukraine 1 Hryvnia 1995')])
    soup = BeautifulSoup(request.content, 'lxml')
    link = soup.find('div', {'class': 'description_piece'})
    print (link)

numista()
Результат - None, вроде нет такого diva. Но он есть.
Почитал по сети, могут js скрипты блокировать контент (точнее, создавать динамически). Но не пойму, как это вычислить и обойти
 
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Доброго времени суток!
Продолжу здесь, так как скрипт тот же, отметки для установки темы решенной нет, так что и плодить новые пока не вижу смысла.
Задача примерно та же, что и ранее - парсинг, только другого сайта.
Результат - None, вроде нет такого diva. Но он есть.
Почитал по сети, могут js скрипты блокировать контент (точнее, создавать динамически). Но не пойму, как это вычислить и обойти
Добавил в ваш код строку:
Python:
print(url)
выдало:
Код:
https://en.numista.com/catalogue/index.php?
поэтому и None в результате
 

asmadeus

Новичок
Пользователь
Июл 27, 2020
17
1
3
Там и должно так выдать, ведь параметры далее в request.
Ошибка у меня в параметрах.
Было:
Python:
 request = session.get(url, headers=headers,
    params=[('q', 'Ukraine 1 Hryvnia 1995')])
А надо:
Python:
 request = session.get(url, headers=headers,
    params=[('r', 'Ukraine 1 Hryvnia 1995')])
 

asmadeus

Новичок
Пользователь
Июл 27, 2020
17
1
3
Приветствую!
Этот код, оказывается, не сработает, если в таблице есть дополнительная колонка.
Вот тут сработает:
https://ru.ucoin.net/coin/french_polinesia-20-francs-1972-2005/?tid=47083

А вот тут нет:
https://ru.ucoin.net/coin/poland-5-zlotych-1994-2021/?tid=8392

Код (функция, не полностью):
Python:
    def get_link(self, domain):
        links = []
        link = ''
        self.get_coins_from_list('pri')
        host = 'https://' + domain
        session = requests.Session()
        for i in range(len(self.sch)):
            if domain == 'ru.ucoin.net':
                url = (host + '/catalog/?')
                search = self.sch[i]
                yahr = re.sub(r'.*(\d{4})\sKM.*', r'\1', search[0])
                r = session.get(url, headers=HEADERS, params=[('q', search[0])])
                if r.status_code == 200:
                    sp = BeautifulSoup(r.text, 'html.parser')
                    try:
                        # Косяк с монетами евро Германии, и монетами Польши 2 и 5 злотых из-за наличия дополнительной
                        # колонки в таблице
                        link = sp.find('table', {'class': 'coin'}).find('a').get('href')
                        request = session.get(host + link, headers=HEADERS)
                        sp2 = BeautifulSoup(request.content, 'html.parser')
                        table = sp2.find_all('tr', {"class": "tr-hr"})
                        if table:
                            # Не идет по этой ветке
                            # Ранее надо получать монетный двор для монет Германии и удалять его для Польши
                            for s in table:
                                if yahr in s['data-href']:
                                    link = host + s['data-href']
                        else:
                            # Не идет по этой ветке
                            link = host + link
                    except AttributeError:
                        link = "Нет результата поиска, надо делать вручную"
                        # Не идет по этой ветке
                else:
                    QMessageBox.critical(self.app, "Ошибка", "Ошибка получения ссылки!")
                links.append(link)
            else:
                url = (host + '/catalogue/index.php?')
                search = self.sch[i]
                r = session.get(url, headers=HEADERS, params=[('r', search[1])])
                if r.status_code == 200:
                    sp = BeautifulSoup(r.text, 'html.parser')
                    try:
                        link = sp.find('div', {'class': 'description_piece'}).find('a').get('href')
                        link = host + link
                    except AttributeError:
                        link = "Нет результата поиска, надо делать вручную"
                else:
                    QMessageBox.critical(self.app, "Ошибка", "Ошибка получения ссылки!")
                links.append(link)
        return links

Вопрос в том, как в этот участок
Python:
.........                     
table = sp2.find_all('tr', {"class": "tr-hr"})

                        if table:

                            # Не идет по этой ветке

                            # Ранее надо получать монетный двор для монет Германии и удалять его для Польши

                            for s in table:

                                if yahr in s['data-href']:

                                    link = host + s['data-href']
............
вписать кроме колонки yahr (год) еще колонку при ее наличии. Или не учитывать ее вовсе

Пробовал так:
Python:
.........                     
mnt = 'G'
table = sp2.find_all('tr', {"class": "tr-hr"})

                        if table:

                          for s in table:

                                if yahr  and mnt in s['data-href']:

                                    link = host + s['data-href']
............
то результата нет
 

Форум IT Специалистов