Несколько вопросов по вытаскиваю информации из текстовых файлов

Наги

Пользователь
Пользователь
Окт 25, 2020
74
5
8
Всем доброго времени суток!
Я уже долгое время занимаюсь этим кодом и уже пару раз сюда насчет него писала... и вот, появилась еще пара вопросов. Вот код:

Python:
from bs4 import BeautifulSoup
import requests
import re
import pandas as pd

b_name_list = []
starttime_list = []
starttimeUT_list = []
duration_list = []
fluence_list = []
peak_fl_list = []
peak_fl_starttime_list = []
mode_list = []
redshift_list = []

def write_csv():
    data = dict(b_name=b_name_list, starttime=starttime_list, starttimeUT=starttimeUT_list,
                duration=duration_list, fluence=fluence_list, peak_fl=peak_fl_list, mode=mode_list, peak_fl_starttime=peak_fl_starttime_list, redshift=redshift_list)
    df = pd.DataFrame(data)
    df.to_csv(r'Results.csv', sep=';', index=False)


with open("List_of_links.txt") as f:
    lines = [line.rstrip('\n') for line in f]

for line in lines:
    print(line)
    response = requests.get(line)
    soup = BeautifulSoup(response.content, "lxml")
    ptag = soup.find(lambda tag: tag.name == 'p')

    string = str(ptag)

    b_name = re.search('GRB \d{6}\w', string)
    if b_name != None:
        b_name = b_name.group(0).replace('\n', '')
        print(b_name)
    else:
        b_name = '--'
        print('b_name')

    starttime = re.search('T0=\d{1,5}.\d{1,5}', string)
    if starttime != None:
        starttime = starttime.group(0).replace('T0=', '')
        print(starttime)
    else:
        starttime = '--'
        print(starttime)

    starttimeUT = re.search('\d{2}:\d{2}:\d{2}.\d{1,5}', string)
    if starttimeUT != None:
        starttimeUT = starttimeUT.group(0)
        print(starttimeUT)
    else:
        starttimeUT = '--'
        print(starttimeUT)

    if string.find('duration of ~') != -1:
        duration = string[string.find('duration of ~'):string.find(' s.')]
        duration = duration[duration.find('~'):]
        duration = duration.replace('~', ' ')
        print(duration)
    elif string.find('duration of~') != -1:
        duration = string[string.find('duration of~'):string.find(' s\n')]
        duration = duration[duration.find('of~') + 2:]
        duration = duration.replace('~', ' ')
        print(duration)
    elif string.find('duration is ~') != -1:
        duration = string[string.find('duration is ~'):string.find(' s\n')]
        duration = duration[duration.find('~'):]
        duration = duration.replace('~', ' ')
        duration = duration.replace('s.', ' ')
        print(duration)
    else:
        duration = '--'
        print(duration)

    fluence = string[string.find('fluence of'):string.find(' erg/')]
    if fluence != None:
        fluence = fluence[fluence.find('of ') + 3:].replace('uence of', '').replace('\n', '')
        print(fluence)
    else:
        fluence = '--'
        print(fluence)

    peak_fl = re.search(('\d{1}.\d{1,3}-s |\d{1,3}-ms'), string)
    if peak_fl != None:  
        peak_fl = peak_fl.group(0)
        #peak_fl = re.sub(r'\d{1,3}-ms', '0.0+\d{1,3}', peak_fl)
        peak_fl = peak_fl.replace('-ms', '').replace('-s', '')
        print(peak_fl)
    else:
        peak_fl = '--'
        print(peak_fl)

    if string.find('measured from T0+') != -1:
        peak_fl_starttime = string[string.find('measured from T0+'):string.find(' s,')]
        peak_fl_starttime = peak_fl_starttime[peak_fl_starttime.find('+'):]
        peak_fl_starttime = peak_fl_starttime.replace('+', ' ')
        print(peak_fl_starttime)
    elif string.find('measured from ~T0(BAT)+') != -1:
        peak_fl_starttime = string[string.find('measured from ~T0(BAT)+'):string.find(' s,')]
        peak_fl_starttime = peak_fl_starttime[peak_fl_starttime.find('+'):]
        peak_fl_starttime = peak_fl_starttime.replace('+', ' ')
        print(peak_fl_starttime)
    else:
        peak_fl_starttime = '--'
        print(peak_fl_starttime)

    mode = re.search('triggered |waiting mode', string)
    if mode != None:
        mode = mode.group(0)
        print(mode)
    else:
        mode = '--'
        print(mode)

    redshift = re.search('z=\d{1,2}.\d{1,3}', string)
    if redshift != None:
        redshift = redshift.group(0).replace('z=', '')
        print(mode)
    else:
        redshift = '--'
        print(redshift)


    b_name_list.append(b_name)
    starttime_list.append(starttime)
    starttimeUT_list.append(starttimeUT)
    duration_list.append(duration)
    fluence_list.append(fluence)
    peak_fl_list.append(peak_fl)
    peak_fl_starttime_list.append(peak_fl_starttime)
    mode_list.append(mode)
    redshift_list.append(redshift)

write_csv()

Вопросы у меня по таблице, которая формируется в результате выполнения кода:
1. В колонке duration для строки 4 (GRB 201103B) неправильно отображается значение 105. Если на него нажать, то появится весь текст исходного файла. А нужно только "105". Как это исправить?(
2. Для колонки peak_fl_starttime для строки 13 (GRB 200826B) та же проблема. Не пойму, почему( И почему-то не отображаются значения для GRB 200716C и GRB 201103B, хотя они в исходных файлах есть. И они того же вида, что все остальные.
3. Для колонки peak_fl мне нужно все миллисекунды перевести в секунды. То есть, там, например, "64", а мне нужно, чтобы стало "0,064". Я попробовала сделать это следующей строчкой кода: peak_fl = re.sub(r'\d{1,3}-ms', '0.0+\d{1,3}', peak_fl), но не работает. Просто на "0.0" заменяет, а так, чтобы было 0.0 + исходное значение - нет. Как поправить?(

Работаю я на Python 3.9.0.
Заранее благодарю за любую помощь!) А также прикладываю список ссылок, с которыми работает код.
 

Вложения

  • List_of_links.txt
    772 байт · Просмотры: 3

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Ошибки возникают потому, что при парсинге не обрабатываются частные случаи.
Вот код с исправлениями (комментариями отмечены изменения):
Python:
from bs4 import BeautifulSoup
import requests
import re
import pandas as pd

b_name_list = []
starttime_list = []
starttimeUT_list = []
duration_list = []
fluence_list = []
peak_fl_list = []
peak_fl_starttime_list = []
mode_list = []
redshift_list = []

def write_csv():
    data = dict(b_name=b_name_list, starttime=starttime_list, starttimeUT=starttimeUT_list,
                duration=duration_list, fluence=fluence_list, peak_fl=peak_fl_list, mode=mode_list, peak_fl_starttime=peak_fl_starttime_list, redshift=redshift_list)
    df = pd.DataFrame(data)
    df.to_csv(r'Results.csv', sep=';', index=False)


with open("List_of_links.txt") as f:
    lines = [line.rstrip('\n') for line in f]

for line in lines:
    print(line)
    response = requests.get(line)
    soup = BeautifulSoup(response.content, "lxml")
    ptag = soup.find(lambda tag: tag.name == 'p')

    string = str(ptag)

    b_name = re.search('GRB \d{6}\w', string)
    if b_name != None:
        b_name = b_name.group(0).replace('\n', '')
        print(b_name)
    else:
        b_name = '--'
        print('b_name')

    starttime = re.search('T0=\d{1,5}.\d{1,5}', string)
    if starttime != None:
        starttime = starttime.group(0).replace('T0=', '')
        print(starttime)
    else:
        starttime = '--'
        print(starttime)

    starttimeUT = re.search('\d{2}:\d{2}:\d{2}.\d{1,5}', string)
    if starttimeUT != None:
        starttimeUT = starttimeUT.group(0)
        print(starttimeUT)
    else:
        starttimeUT = '--'
        print(starttimeUT)

    if string.find('duration of ~') != -1:
        duration = string[string.find('duration of ~'):string.find(' s.')]
        duration = duration[duration.find('~'):]
        duration = duration.replace('~', ' ')
        print(duration)
    elif string.find('duration of~') != -1:
        duration = string[string.find('duration of~'):string.find(' s\n')]
        duration = duration[duration.find('of~') + 2:]
        duration = duration.replace('~', ' ')
        print(duration)
    elif string.find('duration is ~') != -1:
        # Ответ на вопрос №1
        x1 = string.find('duration is ~')
        x2 = string[x1:].find(' s.')
        duration = string[x1:x1 + x2]
        ###################
        duration = duration[duration.find('~'):]
        duration = duration.replace('~', ' ')
        duration = duration.replace('s.', ' ')
        print(duration)
    else:
        duration = '--'
        print(duration)

    fluence = string[string.find('fluence of'):string.find(' erg/')]
    if fluence != None:
        fluence = fluence[fluence.find('of ') + 3:].replace('uence of', '').replace('\n', '')
        print(fluence)
    else:
        fluence = '--'
        print(fluence)

    peak_fl = re.search(('\d{1}.\d{1,3}-s |\d{1,3}-ms'), string)
    if peak_fl != None: 
        peak_fl = peak_fl.group(0)
        # Ответ на вопрос №3
        if 'ms' in peak_fl:
            peak_fl = peak_fl.replace('-ms', '')
            try:
                peak_fl = str(float(peak_fl) / 1000)
            except ValueError:
                pass
        ####################
        else:
            peak_fl = peak_fl.replace('-s', '')
        print(peak_fl)
    else:
        peak_fl = '--'
        print(peak_fl)

    if string.find('measured from T0+') != -1:
        # Ответ на вопрос №2
        peak_fl_starttime = string[string.find('measured from T0+'):string.find(' s,')]
        if peak_fl_starttime == '':
            x1 = string.find('measured from T0+')
            x2 = string[x1:].find(' s,')
            peak_fl_starttime = string[x1:x1 + x2]
        if len(peak_fl_starttime) > 25:
            x1 = string.find('measured from T0+')
            x2 = string[x1:].find(',')
            peak_fl_starttime = string[x1:x1 + x2]
        ####################
        peak_fl_starttime = peak_fl_starttime[peak_fl_starttime.find('+'):]
        peak_fl_starttime = peak_fl_starttime.replace('+', ' ')
        print(peak_fl_starttime)
    elif string.find('measured from ~T0(BAT)+') != -1:
        peak_fl_starttime = string[string.find('measured from ~T0(BAT)+'):string.find(' s,')]
        peak_fl_starttime = peak_fl_starttime[peak_fl_starttime.find('+'):]
        peak_fl_starttime = peak_fl_starttime.replace('+', ' ')
        print(peak_fl_starttime)
    else:
        peak_fl_starttime = '--'
        print(peak_fl_starttime)

    mode = re.search('triggered |waiting mode', string)
    if mode != None:
        mode = mode.group(0)
        print(mode)
    else:
        mode = '--'
        print(mode)

    redshift = re.search('z=\d{1,2}.\d{1,3}', string)
    if redshift != None:
        redshift = redshift.group(0).replace('z=', '')
        print(mode)
    else:
        redshift = '--'
        print(redshift)


    b_name_list.append(b_name)
    starttime_list.append(starttime)
    starttimeUT_list.append(starttimeUT)
    duration_list.append(duration)
    fluence_list.append(fluence)
    peak_fl_list.append(peak_fl)
    peak_fl_starttime_list.append(peak_fl_starttime)
    mode_list.append(mode)
    redshift_list.append(redshift)

write_csv()
 
  • Мне нравится
Реакции: Наги

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 669
477
83
добавлю свои 5 копеек
полный код
Python:
from bs4 import BeautifulSoup
import requests
import re
import pandas as pd

b_name_list = []
starttime_list = []
starttimeUT_list = []
duration_list = []
fluence_list = []
peak_fl_list = []
peak_fl_starttime_list = []
mode_list = []
redshift_list = []

def write_csv():
    data = dict(b_name=b_name_list, starttime=starttime_list, starttimeUT=starttimeUT_list,
                duration=duration_list, fluence=fluence_list, peak_fl=peak_fl_list, mode=mode_list,
                peak_fl_starttime=peak_fl_starttime_list, redshift=redshift_list)
    df = pd.DataFrame(data)
    df.to_csv(r'Results.csv', sep=';', index=False)


with open("List_of_links.txt") as f:
    lines = [line.rstrip('\n') for line in f]

for line in lines:
    print(line)
    response = requests.get(line)
    soup = BeautifulSoup(response.content, "lxml")
    ptag = soup.find(lambda tag: tag.name == 'p')

    string = str(ptag)

    b_name = re.search('GRB \d{6}\w', string)
    if b_name != None:
        b_name = b_name.group(0).replace('\n', '')
        print(b_name)
    else:
        b_name = '--'
        print('b_name')

    starttime = re.search('T0=\d{1,5}.\d{1,5}', string)
    if starttime != None:
        starttime = starttime.group(0).replace('T0=', '')
        print(starttime)
    else:
        starttime = '--'
        print(starttime)

    starttimeUT = re.search('\d{2}:\d{2}:\d{2}.\d{1,5}', string)
    if starttimeUT != None:
        starttimeUT = starttimeUT.group(0)
        print(starttimeUT)
    else:
        starttimeUT = '--'
        print(starttimeUT)

    if string.find('duration of ~') != -1:
        duration = string[string.find('duration of ~'):string.find(' s.')]
        duration = duration[duration.find('~'):]
        duration = duration.replace('~', ' ')
        print(duration)
    elif string.find('duration of~') != -1:
        duration = string[string.find('duration of~'):string.find(' s\n')]
        duration = duration[duration.find('of~') + 2:]
        duration = duration.replace('~', ' ')
        print(duration)
    elif string.find('duration is ~') != -1:
        duration = string[string.find('duration is ~'):string.find('duration is ~') + 19]
        duration = duration[duration.find('~'):]
        duration = duration.replace('~', ' ')
        duration = duration.replace(' s.', ' ')
        print(duration)
    else:
        duration = '--'
        print(duration)

    fluence = string[string.find('fluence of'):string.find(' erg/')]
    if fluence != None:
        fluence = fluence[fluence.find('of ') + 3:].replace('uence of', '').replace('\n', '')
        print(fluence)
    else:
        fluence = '--'
        print(fluence)

    peak_fl = re.search(('\d{1}.\d{1,3}-s |\d{1,3}-ms'), string)
    if peak_fl != None:
        peak_fl = peak_fl.group(0)
        if peak_fl.find('-ms') != -1:
            peak_fl = float(peak_fl.replace('-ms', '')) / 1000
            peak_fl = str(peak_fl)
        peak_fl = peak_fl.replace('-ms', '').replace('-s', '')
        print(peak_fl)
    else:
        peak_fl = '--'
        print(peak_fl)

    if string.find('measured from T0+') != -1:
        peak_fl_starttime = string[string.find('measured from T0+'):string.find('measured from T0+') + 22]
        peak_fl_starttime = peak_fl_starttime[peak_fl_starttime.find('+'):]
        peak_fl_starttime = peak_fl_starttime.replace('+', ' ')
        print(peak_fl_starttime)
    elif string.find('measured from ~T0(BAT)+') != -1:
        peak_fl_starttime = string[string.find('measured from ~T0(BAT)+'):string.find(' s,')]
        peak_fl_starttime = peak_fl_starttime[peak_fl_starttime.find('+'):]
        peak_fl_starttime = peak_fl_starttime.replace('+', ' ')
        print(peak_fl_starttime)
    else:
        peak_fl_starttime = '--'
        print(peak_fl_starttime)

    mode = re.search('triggered |waiting mode', string)
    if mode != None:
        mode = mode.group(0)
        print(mode)
    else:
        mode = '--'
        print(mode)

    redshift = re.search('z=\d{1,2}.\d{1,3}', string)
    if redshift != None:
        redshift = redshift.group(0).replace('z=', '')
        print(mode)
    else:
        redshift = '--'
        print(redshift)


    b_name_list.append(b_name)
    starttime_list.append(starttime)
    starttimeUT_list.append(starttimeUT)
    duration_list.append(duration)
    fluence_list.append(fluence)
    peak_fl_list.append(peak_fl)
    peak_fl_starttime_list.append(peak_fl_starttime)
    mode_list.append(mode)
    redshift_list.append(redshift)

write_csv()
 
  • Мне нравится
Реакции: Наги

Наги

Пользователь
Пользователь
Окт 25, 2020
74
5
8
stud_55, regnor, огромное вам спасибо, теперь все хорошо!))

stud_55, можно ли Вас попросить пояснить эту строку?
duration = string[x1:x1 + x2] - не совсем понимаю, что такое х1, х2...

regnor, можно ли Вас попросить пояснить эти строчки?
peak_fl = float(peak_fl.replace('-ms', '')) / 1000 - это просто числа в строках делим на 1000?
peak_fl = str(peak_fl) - а это приводим peak_fl к строке?

И вдогонку еще вопрос небольшой. Как я могу сделать так, чтобы все значения в моей таблице были разделены пробелами, а не табами? ._.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
@stud_55, можно ли Вас попросить пояснить эту строку?
duration = string[x1:x1 + x2] - не совсем понимаю, что такое х1, х2...
x1, x2 - это индексы подстрок 'duration is ~' и ' s.' в строке string.
string[x1:x1 + x2] - это срез строки между этими индексами, который содержит нужно значение (duration).
 
  • Мне нравится
Реакции: Наги

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 669
477
83
@regnor, можно ли Вас попросить пояснить эти строчки?
peak_fl = float(peak_fl.replace('-ms', '')) / 1000 - это просто числа в строках делим на 1000?
peak_fl = str(peak_fl) - а это приводим peak_fl к строке?
все верно
чтобы поделить строку на число, нужно привести ее к числу, при этом убрав лишние символы
и потом обратно преобразовать в строку что можно было с ней работать как со строкой

И вдогонку еще вопрос небольшой. Как я могу сделать так, чтобы все значения в моей таблице были разделены пробелами, а не табами?
не понятен вопрос, у вас данные разделены точкой с запятой, у вас файл csv, а не tsv...
 
Последнее редактирование:
  • Мне нравится
Реакции: Наги

Наги

Пользователь
Пользователь
Окт 25, 2020
74
5
8
x1, x2 - это индексы подстрок 'duration is ~' и ' s.' в строке string.
string[x1:x1 + x2] - это срез строки между этими индексами, который содержит нужно значение (duration).
Спасибо за пояснение!
 

Наги

Пользователь
Пользователь
Окт 25, 2020
74
5
8
все верно
чтобы поделить строку на число, нужно привести ее к числу, при этом убрав лишние символы
и потом обратно преобразовать в строку что можно было с ней работать как со строкой


не понятен вопрос, у вас данные разделены точкой с запятой, у вас файл csv, а не tsv...
Спасибо за пояснение!) С форматом файла поняла, буду разбираться...
 

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