Соскоб в сети обзоров только за прошедший год - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь отсканировать отзывы, которые были сделаны только от tripadvisor для конкретной авиакомпании Spicejet.Ссылка: https://www.tripadvisor.com/Airline_Review-d8728949-Reviews-or60-SpiceJet#REVIEWS

Но существует несоответствие в сохранении дат обзоров, поскольку некоторые из них имеют значение класса span: <span class="ratingDate"> Reviewed October 22, 2018 </span>

А некоторые в названии:

<span class="ratingDate relativeDate" title="October 23, 2018"> Reviewed 5 weeks ago </span>

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

Код:

date = items.find(class_="ratingDate").get("title") date = dt.strptime(date, "%B %d, %Y") if (date > dt.strptime(('November 26 2017'),"%B %d %Y")): date = items.find('span', class_='ratingDate')['title']

Вывод:

«свойуправляемый »

(« 23 октября 2018 г. »)

<ipython-input-72-3d5de04a2794> in get_info()
  6         for items in soup.find_all(class_="innerBubble"):
  7             date = items.find(class_="ratingDate").get("title")
  ----> 8             date = dt.strptime(date, "%B %d, %Y")
  9             if (date > dt.strptime(('November 26 2017'),"%B %d %Y")):
 10                 print("===========================================")

 TypeError: strptime() argument 1 must be str, not None

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Вы можете проделать большую работу или отследить, откуда поступают данные, и немного размыть источник, пока он не выдаст что-то более привлекательное.Здесь похоже, что данные загружаются из:
https://www.tripadvisor.com/AirlineTips
, что, как вы заметили, ужасно ужасно.

Точный звонок, который он сделал для меня, был:
https://www.tripadvisor.com/AirlineTips?d=8728949&inline=true

Который выплевывает:

<div class="page page1">
<div class="tip">
<div class="memberOverlayLink" id="UID_-SRC_635739734" onmouseover="requireCallIfReady('members/memberOverlay', 'initMemberOverlay', event, this, this.id, 'Reviews', 'user_name_photo');" data-anchorWidth="30">
<div class="circularAvWrap smallCircularAvWrap profile_UID_-SRC_635739734">
<img src="https://media-cdn.tripadvisor.com/media/photo-l/01/2e/70/85/avatar006.jpg" class="avatar" width="28" height="28"/>
</div>
</div> <div class="tipText">
<blockquote>&#x201c;Value for Money&#x201d;</blockquote>
<span class="ui_bubble_rating bubble_4" alt="4.0 of 5 bubbles"></span>
Santhoshpp, 2 days ago
<span class="pipe">|</span> <a href="/ShowUserReviews-g1-d8728949-r635739734-SpiceJet-World.html" onclick="ta.trackEventOnPage('Tab Content', 'read_review', 'Read Review');">Read review</a> </div> </div>
<div class="tip">
<div class="memberOverlayLink" id="UID_-SRC_635711432" onmouseover="requireCallIfReady('members/memberOverlay', 'initMemberOverlay', event, this, this.id, 'Reviews', 'user_name_photo');" data-anchorWidth="30">
<div class="circularAvWrap smallCircularAvWrap profile_UID_-SRC_635711432">
<img src="https://media-cdn.tripadvisor.com/media/photo-l/01/2e/70/99/avatar025.jpg" class="avatar" width="28" height="28"/>
</div>
</div> <div class="tipText">

Ммм, отвратительно.

Давайте попробуем изменить inline=false по этому запросу ... https://www.tripadvisor.com/AirlineTips?d=8728949&inline=false
дает нам

script> new Asset.css('https://static.tacdn.com/css2/accommodations/room_tips_overlay-v22801712797b.css');</script>
<div id="TIPSOVERLAY" class="wrap">
<div class="title">
<span class="fl">
See travel tips for airlines </span>
</div>
<div class="content">
<div class="tip"><span class="tipBody">&#x201c;Value for Money&#x201d; (Santhoshpp) </span>
<div class="rsImg">
<span class="ui_bubble_rating bubble_4"></span>
<span class="dateAuthor">Nov 25, 2018</span>
</div>
</div>
<div class="tip"><span class="tipBody">&#x201c;carry your own entertainment stuff and be ready if your flight gets delayed&#x201d; (vbroams) </span>
<div class="rsImg">
<span class="ui_bubble_rating bubble_3"></span>
<span class="dateAuthor">Nov 25, 2018</span>
</div>
</div>

О, сексуальные ракушки, Бэтмен!Вот оноТеперь нам не нужно бороться с датами в Python или чем-то еще.

tl; dr
Не чистите суп, чистите источник.Под любым динамическим контентом есть API.

0 голосов
/ 27 ноября 2018

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

<span class="ratingDate relativeDate" title="October 26, 2018">Reviewed 4 weeks ago
</span>

Вы также можете получить текст обзора с помощью селектора классов.Zip и поверните к списку.

Ниже приведен контур без фильтрации даты.Фильтруйте даты либо раньше, чем это (но тогда вам понадобится индекс для связи между списками, чтобы соответствовать дате и тексту обзора), или отсюда.Все даты в едином формате.

import requests
from bs4 import BeautifulSoup
url = 'https://www.tripadvisor.com/Airline_Review-d8728949-Reviews-or60-SpiceJet#REVIEWS'
data = requests.get(url).content
soup = BeautifulSoup(data,'lxml')
dateStrings = soup.select('.ratingDate')  
reviewStrings = soup.select('.partial_entry')
reviewDates = [date['title'].strip() if len(date['class']) == 2 else date.text.strip().replace('Reviewed ','') for date in dateStrings]
reviews = [review.text.strip() for review in reviewStrings]
allInfo = list(zip(updatedDates,reviews))
0 голосов
/ 27 ноября 2018

Насколько я понимаю, вам не нужно сравнивать оба значения даты, так как они оба будут означать одну и ту же дату.Таким образом, для каждого обзора проверьте, существует ли дата класса диапазона или дата заголовка.Если оба существуют, просто отметьте один.Проверка может быть сделана с strptime .

Для даты заголовка вам потребуется timedelta .

span_date = None
title_date = None
one_year_ago_date = datetime.now().replace(year=dt.year-3)

# ADD CODE HERE to get date strings for span_date and title_date

# Assume span_date = "October 22, 2018"
review_date = None
if span_date is not None:
    review_date = datetime.datetime.strptime(span_date, "%B %d, %Y").date()

# Assume title_date = "5 weeks ago"
elif title_date is not None:
    title_date = [title_date .split()[:2]]
    time_dict = dict((fmt, float(amount)) for amount,fmt in title_date)
    dt = datetime.timedelta(**time_dict)
    review_date = datetime.datetime.today() - dt

# Check if review_date is earlier than one year ago
if review_date.date() < one_year_ago_date:
    print("Save this review")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...