Html Parser извлекается с предыдущей веб-страницы

У меня есть скрипт, который загружает страницу и сохраняет кучу идентификаторов данных из нескольких контейнеров. Затем я хочу открыть новые URL-адреса, добавив указанные идентификаторы данных в конец URL-адресов. Для каждого URL-адреса я хочу найти все hrefs и сравнить их со списком конкретных ссылок, и если какие-либо из них совпадают, я хочу сохранить эту ссылку и некоторые другие данные в таблице.

Мне удалось заставить его открыть URL-адрес с добавленным идентификатором данных, но когда я пытаюсь найти элементы на новой странице, он либо извлекает их из первого URL-адреса, который был проанализирован, если я снова пытаюсь найти все из супа, либо я постоянно получаю эта ошибка, когда я пытаюсь запустить другой html.parser.

У объекта ResultSet нет атрибута findAll. Вероятно, вы рассматриваете список элементов как один элемент. Вы вызвали find_all(), когда хотели вызвать find()?

Неужели нельзя запустить другой парсер или я просто что-то не так делаю?

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup as soup
from selenium.webdriver.common.action_chains import ActionChains

url = "http://csgo.exchange/id/76561197999004010#x"

driver = webdriver.Firefox()

driver.get(url)
import time
time.sleep(15)
html = driver.page_source
soup = soup(html, "html.parser")

containers = soup.findAll("div",{"class":"vItem"})

print(len(containers))
data_ids = [] # Make a list to hold the data-id's

for container in containers:
    test = container.attrs["data-id"]
    data_ids.append(test) # add data-id's to the list
    print(str(test))

for id in data_ids:
    url2 = "http://csgo.exchange/item/" + id
    driver.get(url2)
    import time
    time.sleep(2)   
    soup2 = soup(html, "html.parser")
    containers2 = soup2.findAll("div",{"class":"bar"})
    print(str(containers2))

with open('scraped.txt', 'w', encoding="utf-8") as file:
    for id in data_ids:
        file.write(str(id)+'\n') # write every data-id to a new line

person CodeOrDie    schedule 10.03.2019    source источник
comment
Источник страницы для этого первого URL-адреса (csgo.exchange/id/76561197999004010#x) не Первое, что я замечаю, — это отсутствие элементов div с классом vItem. Как вы добиваетесь результатов с первого раза? Для вашего вопроса могут быть полезны один или два примера идентификатора, потому что тогда мы могли бы перейти по URL-адресу и просмотреть исходный код страницы.   -  person C. Peck    schedule 10.03.2019
comment
Существует около 885 элементов div класса vItem. У меня нет проблем с получением идентификаторов. Как и человек, который ранее помогал мне с моей последней проблемой. Но вот несколько примеров. 15653916980 15653916960 15631554103   -  person CodeOrDie    schedule 10.03.2019
comment
Я предполагаю, что когда вы пошли, чтобы загрузить страницу, она не полностью загрузилась. Иногда страница может зависнуть, а иногда она открывается сразу. Я планирую заставить его ждать, пока элемент не появится, прежде чем он продолжится в будущем, но я не знаю, как это сделать прямо сейчас, поэтому 15-секундный сон является заполнителем.   -  person CodeOrDie    schedule 10.03.2019
comment
Что я действительно пытаюсь вытащить, так это все ссылки в истории потока на каждой странице, подобной этой. csgo.exchange/item/15653916980 Затем я хочу сравнить каждую из них со списком ссылок. чтобы увидеть, совпадают ли какие-либо из них.   -  person CodeOrDie    schedule 10.03.2019


Ответы (2)


Не уверен, что именно вы хотите от каждой страницы. Вы должны добавить ожидания. Я добавляю ожидание поиска ссылок в разделе истории потоков на каждой странице (если они есть). Он должен иллюстрировать идею.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

url = 'http://csgo.exchange/id/76561197999004010'
driver = webdriver.Chrome()
driver.get(url)
ids = [item.get_attribute('data-id') for item in WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "[data-id]")))]
results = []
baseURL = 'http://csgo.exchange/item/'
for id in ids:
    url = baseURL + id
    driver.get(url)
    try:
        flowHistory = [item.get_attribute('href') for item in WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#tab-history-flow [href]")))]
        results.append([id, flowHistory])
    except:
        print(url)
person QHarr    schedule 10.03.2019
comment
Данг. Итак, это совершенно другой подход даже без использования BS4. Это работает довольно хорошо, за исключением случаев, когда дело доходит до элемента, у которого нет ссылок. Он приостанавливается на длительный период времени, но в конечном итоге продолжается. Я предполагаю, что это связано с методом try. Хотя я не знаю, почему он так долго висит. Излишне говорить, что я хочу в конечном итоге отфильтровать множество этих ненужных предметов, таких как футляры, наклейки и медали. - person CodeOrDie; 10.03.2019
comment
Это время, которое я даю ему подождать. Вы можете уменьшить это число с 10 до меньшего числа. Эта строка: [item.get_attribute('href') для элемента в WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, #tab-history-flow [href]))) - person QHarr; 10.03.2019
comment
Что касается того, что я хочу от каждой страницы. Это будет имя элемента, расположенное на панели классов div. Ссылка на тот элемент, который является ссылкой, которую он посетил в первую очередь. А потом все ссылки в истории потока, которые он уже получает. И затем, в конце концов, я хочу сравнить эти hrefs со списком ссылок и сохранить только те, которые соответствуют. Но я ценю помощь. Сам бы я в этом не разобрался. Я начал биться головой о стену. - person CodeOrDie; 10.03.2019
comment
О, я понял. Он работает быстро, когда загружается, но зависает, если его нет. Имеет смысл. Да, я просто уменьшу это до 3 секунд. - person CodeOrDie; 10.03.2019

person    schedule
comment
Что касается проверки соответствия hrefs flowHistory элементу списка. Я делаю это правильно? Потому что первый элемент, который он проверяет, должен печатать csgo.exchange/profiles/76561198149324950, но я не получаю что-нибудь взамен. - person CodeOrDie; 10.03.2019
comment
Хорошо, я продвинулся немного дальше, используя if any(elem in flowHistory for elem in pros): но он добавляет все hrefs для этого элемента, а не только те, которые соответствуют. Поэтому мне нужно выяснить, как просто добавить совпадающие, и я в порядке. - person CodeOrDie; 10.03.2019
comment
Использование для строки в плюсах: если строка в flowHistory match = string, она возвращает первую совпадающую ссылку href, но не возвращает больше, если их больше. Я продолжаю приближаться, но все еще не там. - person CodeOrDie; 10.03.2019
comment
Я занимался делами. Нужно что-нибудь еще? - person QHarr; 10.03.2019
comment
Извините, я не спал всю ночь, поэтому я спал. Я опубликую код, который у меня есть сейчас, но, как я уже сказал, он возвращает только один из совпадающих результатов, а не все из них. - person CodeOrDie; 10.03.2019
comment
Итак, можете ли вы дать мне один URL-адрес и ожидаемое количество совпадений, пожалуйста? - person QHarr; 10.03.2019
comment
Оба URL-адреса, расположенные в списке плюсов, должны совпадать с hrefs, которые извлекаются из первого открываемого элемента. Что касается ожидаемого количества матчей. Трудно сказать, потому что в конечном итоге я хочу сравнить список из 100 или более разных URL-адресов, и все они могут совпадать. Но в данном случае ожидаемое количество совпадений будет равно 2. csgo.exchange/profiles/76561198149324950 csgo.exchange/profiles/76561198152970370 - person CodeOrDie; 10.03.2019
comment
Извиняюсь. Я имею в виду для одного тестового URL-адреса, какие ожидаемые URL-адреса возвращаются (до сопоставления). Это позволяет мне отлаживать ожидаемые значения. - person QHarr; 10.03.2019
comment
с какого URL будут возвращены ожидаемые ссылки? Вот этот? csgo.exchange/profiles/76561198149324950 - person QHarr; 10.03.2019
comment
Спасибо. Я взгляну. - person QHarr; 10.03.2019
comment
Я делаю это 151 URL, который будет возвращен, а не ваш 188. - person QHarr; 10.03.2019
comment
Хм, я не знаю, почему это было бы иначе. - person CodeOrDie; 10.03.2019
comment
Вот что возвращает мой код, если вы полностью сгладите вложенные списки. pastebin.com/A8wejFxz - person QHarr; 10.03.2019
comment
Если вы поместите мой селектор css в окно поиска инструментов разработчика, вы увидите, что он соответствует 151. Вы можете переключаться между каждым совпадением. Он выделяет каждую иконку. - person QHarr; 10.03.2019
comment
Ну, он должен возвращать 151, потому что именно столько элементов в истории потока для этого элемента. - person CodeOrDie; 10.03.2019
comment
запустите код pastebin, где я разворачиваю список, который возвращает мой код. Если вы не разгладите, len будет 1. - person QHarr; 10.03.2019
comment
Да, я запускаю его сейчас, и он напечатал 151. Но я посчитал все ссылки, которые я получил, и тоже было 151, так откуда вы взяли 188? - person CodeOrDie; 10.03.2019
comment
список, который ты мне дал - person QHarr; 10.03.2019
comment
Я вручную посчитал их все на justpaste и получил 151 плюс первый URL, который был самим элементом, то есть 152. Но в любом случае это не очень важно. - person CodeOrDie; 10.03.2019
comment
Итак, вы говорите, что список должен быть сначала разложен? Мне все еще нужен метод для возврата всех совпадений. Метод, который у меня есть сейчас, ищет только первую совпадающую строку. - person CodeOrDie; 10.03.2019
comment
вы можете использовать [любой ](stackoverflow.com/a/55079255/6241235) с генератор, зацикливая полный список результатов и сравнивая с заранее определенным списком. Я бы, вероятно, также использовал set first, чтобы гарантировать отсутствие дубликатов в полном списке результатов. Затем вернитесь к списку. И да, вы можете выполнить распаковку при добавлении во время исходного цикла или переписать, чтобы использовать цикл, а не понимание списка. - person QHarr; 10.03.2019