selenium.common.Exceptions.NoSuchElementException: ข้อความ: {errorMessage: ไม่พบองค์ประกอบที่มี id 'search-facet-city'

ฉันกำลังพยายามขูดเว็บไซต์ต่อไปนี้โดยใช้ Python 3, Selenium และ PhantomJS:

https://health.usnews.com/best-hospitals/search

ฉันจำเป็นต้องค้นหาช่องค้นหาและป้อนข้อความลงไป จากนั้นกด Enter เพื่อสร้างผลการค้นหา ด้านล่างนี้เป็น HTML ที่สอดคล้องกับช่องค้นหาที่ฉันพยายามค้นหา:

<div class="search-field-view">

<div class="block-tight">
    <label class="" for="search-facet-city">
        <input id="search-facet-city" autocomplete="off" name="city" 
type="text" data-field-type="text" placeholder="City, State or ZIP" 
value="" />
    </label>
</div>

</div>

ด้านล่างนี้คือโค้ด Python 3 ของฉันที่พยายามค้นหาช่องค้นหานี้โดยใช้รหัส "search-facet-city"

def scrape(self):
    url = 'https://health.usnews.com/best-hospitals/search'
    location = 'Massachusetts'

    # Instantiate the driver
    driver = webdriver.PhantomJS()
    driver.get(url)
    driver.maximize_window()
    driver.implicitly_wait(10)

    elem = driver.find_element_by_id("search-facet-city")
    elem.send_keys(self.location)

    driver.close()

ฉันต้องขูดผลลัพธ์บางส่วนออกจากหน้าเมื่อป้อนข้อความลงในช่องค้นหา อย่างไรก็ตาม ฉันยังคงได้รับข้อผิดพลาด NoSuchElementException ไม่สามารถค้นหาองค์ประกอบช่องค้นหาได้แม้ว่าจะมีอยู่ก็ตาม ฉันจะแก้ไขปัญหานี้ได้อย่างไร?


person rakeshb    schedule 27.10.2017    source แหล่งที่มา
comment
ข้อผิดพลาดในชื่อโพสต์ของคุณกำลังมองหา search-facet-city เป็น คลาส แต่โค้ดที่โพสต์ของคุณค้นหาเป็น id มันคืออะไร?   -  person John Gordon    schedule 27.10.2017
comment
ขออภัย นั่นเป็นการพิมพ์ผิด มันควรจะเป็นไอดี   -  person rakeshb    schedule 27.10.2017
comment
เมื่อฉันลองดึง URL นั้น ฉันได้รับการตอบกลับ 403 Forbidden แน่ใจเหรอว่าอ่านได้?   -  person John Gordon    schedule 27.10.2017
comment
ใช่ ฉันสามารถอ่าน URL ได้ ฉันสามารถคัดลอกข้อความบางส่วนจาก URL ได้ แต่ปัญหาหลักของฉันคือการค้นหาช่องค้นหาและการป้อนข้อความลงไป ฉันไม่แน่ใจว่าอะไรเป็นสาเหตุของการตอบสนอง 403 Forbidden คุณได้รวมการนำเข้าที่จำเป็นทั้งหมดแล้วหรือยัง?   -  person rakeshb    schedule 27.10.2017
comment
ฉันได้รับ 403 จาก wget บนบรรทัดคำสั่ง เว็บไซต์อาจไม่อนุญาตไคลเอ็นต์ประเภทโรบ็อต ฉันลองใช้ URL ใน Chrome และโหลดหน้าเว็บแล้ว แต่ Mac ของฉันค้างโดยสิ้นเชิงเมื่อฉันพยายามดูแหล่งที่มา ดังนั้นฉันจึงไม่คิดว่าจะได้ไปที่หน้าเว็บนั้นอีก   -  person John Gordon    schedule 27.10.2017
comment
คำตอบเดียวที่ฉันคิดได้คือโค้ด html ที่คุณให้ไว้ที่ด้านบนของโพสต์ไม่ปรากฏในหน้าเว็บเมื่อโหลดครั้งแรก จะต้องมีจาวาสคริปต์บางตัวซึ่งจะเพิ่มโค้ดนั้นลงในเพจแบบไดนามิกเมื่อมีการดำเนินการบางอย่าง   -  person John Gordon    schedule 27.10.2017
comment
โอเค ขอบคุณที่พยายาม ฉันคิดว่าคุณพูดถูกเกี่ยวกับเว็บไซต์ที่ไม่อนุญาตไคลเอนต์ประเภทโรบ็อต ฉันตรวจสอบไฟล์ robots.txt แล้ว และไฟล์นั้นไม่อนุญาตให้เข้าถึงช่องช่องค้นหานั้น ดูเหมือนว่าฉันจะต้องหาวิธีอื่นในการรับผลการค้นหาสำหรับไซต์นี้ โดยอาจเพิ่มตัวย่อของรัฐต่อท้าย URL ดั้งเดิม   -  person rakeshb    schedule 27.10.2017


คำตอบ (1)


ฉันลองสิ่งนี้ด้วย Chrome:

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
from selenium.webdriver.common.keys import Keys


url = 'https://health.usnews.com/best-hospitals/search'
location = 'Massachusetts'
# Instantiate the driver
driver = webdriver.Chrome(executable_path=r'/pathTo/chromedriver')
#driver = webdriver.PhantomJS(executable_path=r'/pathTo/phantomjs')
driver.get(url)
driver.maximize_window()
wait = WebDriverWait(driver, 20)
driver.save_screenshot('out.png');
elem=wait.until(EC.element_to_be_clickable((By.XPATH,"//div[@class='search-field-view']")))
span = elem.find_element_by_xpath("//span[@class='twitter-typeahead']")
input=span.find_element_by_xpath("//input[@class='tt-input' and @name='city']");
input.send_keys(location)
driver.save_screenshot('out2.png');

และมันก็ได้ผล

แต่ถ้าฉันลองใช้ phantomJS ใน driver.save_screenshot('out.png'); ฉันจะได้รับ:

ป้อนคำอธิบายรูปภาพที่นี่

ตามที่ @JonhGordon กล่าวในความคิดเห็น เว็บไซต์จะทำการตรวจสอบบางอย่าง หากคุณต้องการใช้ phantomJS คุณสามารถลองเปลี่ยน desired_capabilities หรือ service_args

person Davide Patti    schedule 27.10.2017