链接到事件点击时如何从网站抓取数据?
How to scrape data from a website when linked to event clicks?
我正在尝试从 Tripadvisor.com 个网页 scrape/extract company/hotel 的网站。我在检查页面时没有看到网站 url。关于如何使用 python 提取网站 url 的任何想法?
提前道歉,因为我最近才开始 'web scraping in Python.'
谢谢。
例如请看图中的两个红色箭头。当我 select 网站 link 时,它会将我带到“http://www.i-love-my-india.com/” - 这是我想使用 Python 提取的内容。
使用 Selenium 试试这个:
import time
from selenium import webdriver
browser = webdriver.Firefox(executable_path="C:\Users\Vader\geckodriver.exe")
# Must install geckodriver (handles your browser)- see instructions on
# http://selenium-python.readthedocs.io/installation.html.
# Change the path to where your geckodriver file is.
browser.get('https://www.tripadvisor.co.uk/Attraction_Review-g304551-d4590508-Reviews-Ashok_s_Taxi_Tours-New_Delhi_National_Capital_Territory_of_Delhi.html')
browser.find_element_by_css_selector('.blEntry.website').click()
#browser.window_handles # Results is 2 tabs opened.
browser.switch_to.window(browser.window_handles[1]) # changes the browser to
# the second one
time.sleep(1) # When I went directly I was getting a 'blank' result, so I put
# a little delay and it worked (I really do not know why).
res = browser.current_url # the URL
print(res)
browser.quit() # Closes the browser
如果您查看该元素,您会注意到重定向 URL 存在(data-ahref
属性),但它在 JS 源代码中的某处进行了编码和解码。不幸的是,它们被缩小和混淆了,因此很难找到解码器函数。因此你有两个选择:
跟随重定向
这就是 Roberval _T_ suggested in his :点击该元素,等待一段时间让页面加载到另一个选项卡中,抓住 URL。这是一个完全有效的答案,在我看来值得点赞,但是当由于某种原因所需的数据不可用时,我总是尝试以下小技巧:
抓取移动网页
抓取移动页面的明显优势是它们比桌面页面更轻量级。但通常,当桌面版本出于某种原因试图隐藏数据时,移动网站也会显示数据。在这种情况下,可以立即抓取移动版本中的所有信息(地址、主页、phone),而无需显式加载 URL。这是我使用移动用户代理 运行 selenium 时页面的样子:
使用 IPhone 的用户代理的示例代码:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
url = 'https://www.tripadvisor.co.uk/Attraction_Review-g304551-d4590508-Reviews-Ashok_s_Taxi_Tours-New_Delhi_National_Capital_Territory_of_Delhi.html'
chrome_options = Options()
chrome_options.add_argument('--user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1')
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get(url)
element = driver.find_element_by_css_selector('div.website.contact_link')
link = element.text
driver.quit()
print(link)
我会推荐使用硒。
我的回答可以看作是对@Roberval T 建议的改进。我认为他的回答非常适合这个特殊情况。
这是我的解决方案。我将指出一些差异以及我认为您应该考虑它们的原因:
import sys
# Selenium
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
# I would use argparse for example
try:
assert len(sys.argv) == 2
url = sys.argv[1]
except AssertionError:
# Invalid arguments
sys.exit()
# Set up the driver
driver = webdriver.Chrome()
driver.get(url)
# Try to load the page a wait until it's loaded
try:
poll_frequency = 5
data_section_id = "taplc_location_detail_header_attractions_0"
data_section = WebDriverWait(driver, poll_frequency).until(EC.presence_of_element_located((By.ID, data_section_id)))
except TimeoutException:
# Could not load page
sys.exit()
# Get the third child ( relative to the data section div that we get by ID )
try:
third_child = data_section.find_elements_by_xpath("./*")[2]
except IndexError:
sys.exit()
# Get the child immediatly under that ( that's how the structure looks)
container_div = third_child.find_elements_by_xpath("./*")[0]
clickable_element = container_div.find_elements_by_xpath("./*")[3]
# Click the node
clickable_element.click()
# Switch tabs
driver.switch_to.window(driver.window_handles[1])
try:
new_page = WebDriverWait(driver, poll_frequency).until(EC.presence_of_element_located((By.TAG_NAME, "body")))
except TimeoutError:
sys.exit()
print(driver.current_url)
assert driver.current_url == "http://www.i-love-my-india.com/"
driver.quit()
首先,在我看来,你应该使用selenium's
特定的等待机制而不是time.sleep()
。这将使您能够更好地微调您的刮刀,也将使其更加可靠。我建议您查看 WebDriverWait
其次,我个人的偏好是避免使用class selectors
。我并不是说他们错了。但经验告诉我,它们可以很容易地改变,而且经常在多个地方使用相同的 class (这就是为什么它是 class )。在这种特殊情况下,选择使用 CSS class
是有效的,因为 class 在一个地方使用。
如果在下一个版本中,在另一个地方使用相同的 class 会怎样?
虽然也不能保证遵循结构,但更改的可能性较小。
使用Chrome
。由于版本 59
,Google Chrome 有一个 headless
选项。在我看来,使用 then Firefox
要容易得多。使用 Firefox
将需要您在生产机器上安装 运行 一个 x server
服务,并通过 geckodriver
将 Firefox
实例连接到该服务器。您可以使用 Chrome
.
跳过所有这些
希望对您有所帮助!
我正在尝试从 Tripadvisor.com 个网页 scrape/extract company/hotel 的网站。我在检查页面时没有看到网站 url。关于如何使用 python 提取网站 url 的任何想法? 提前道歉,因为我最近才开始 'web scraping in Python.' 谢谢。
例如请看图中的两个红色箭头。当我 select 网站 link 时,它会将我带到“http://www.i-love-my-india.com/” - 这是我想使用 Python 提取的内容。
使用 Selenium 试试这个:
import time
from selenium import webdriver
browser = webdriver.Firefox(executable_path="C:\Users\Vader\geckodriver.exe")
# Must install geckodriver (handles your browser)- see instructions on
# http://selenium-python.readthedocs.io/installation.html.
# Change the path to where your geckodriver file is.
browser.get('https://www.tripadvisor.co.uk/Attraction_Review-g304551-d4590508-Reviews-Ashok_s_Taxi_Tours-New_Delhi_National_Capital_Territory_of_Delhi.html')
browser.find_element_by_css_selector('.blEntry.website').click()
#browser.window_handles # Results is 2 tabs opened.
browser.switch_to.window(browser.window_handles[1]) # changes the browser to
# the second one
time.sleep(1) # When I went directly I was getting a 'blank' result, so I put
# a little delay and it worked (I really do not know why).
res = browser.current_url # the URL
print(res)
browser.quit() # Closes the browser
如果您查看该元素,您会注意到重定向 URL 存在(data-ahref
属性),但它在 JS 源代码中的某处进行了编码和解码。不幸的是,它们被缩小和混淆了,因此很难找到解码器函数。因此你有两个选择:
跟随重定向
这就是 Roberval _T_ suggested in his
抓取移动网页
抓取移动页面的明显优势是它们比桌面页面更轻量级。但通常,当桌面版本出于某种原因试图隐藏数据时,移动网站也会显示数据。在这种情况下,可以立即抓取移动版本中的所有信息(地址、主页、phone),而无需显式加载 URL。这是我使用移动用户代理 运行 selenium 时页面的样子:
使用 IPhone 的用户代理的示例代码:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
url = 'https://www.tripadvisor.co.uk/Attraction_Review-g304551-d4590508-Reviews-Ashok_s_Taxi_Tours-New_Delhi_National_Capital_Territory_of_Delhi.html'
chrome_options = Options()
chrome_options.add_argument('--user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1')
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get(url)
element = driver.find_element_by_css_selector('div.website.contact_link')
link = element.text
driver.quit()
print(link)
我会推荐使用硒。
我的回答可以看作是对@Roberval T 建议的改进。我认为他的回答非常适合这个特殊情况。
这是我的解决方案。我将指出一些差异以及我认为您应该考虑它们的原因:
import sys
# Selenium
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
# I would use argparse for example
try:
assert len(sys.argv) == 2
url = sys.argv[1]
except AssertionError:
# Invalid arguments
sys.exit()
# Set up the driver
driver = webdriver.Chrome()
driver.get(url)
# Try to load the page a wait until it's loaded
try:
poll_frequency = 5
data_section_id = "taplc_location_detail_header_attractions_0"
data_section = WebDriverWait(driver, poll_frequency).until(EC.presence_of_element_located((By.ID, data_section_id)))
except TimeoutException:
# Could not load page
sys.exit()
# Get the third child ( relative to the data section div that we get by ID )
try:
third_child = data_section.find_elements_by_xpath("./*")[2]
except IndexError:
sys.exit()
# Get the child immediatly under that ( that's how the structure looks)
container_div = third_child.find_elements_by_xpath("./*")[0]
clickable_element = container_div.find_elements_by_xpath("./*")[3]
# Click the node
clickable_element.click()
# Switch tabs
driver.switch_to.window(driver.window_handles[1])
try:
new_page = WebDriverWait(driver, poll_frequency).until(EC.presence_of_element_located((By.TAG_NAME, "body")))
except TimeoutError:
sys.exit()
print(driver.current_url)
assert driver.current_url == "http://www.i-love-my-india.com/"
driver.quit()
首先,在我看来,你应该使用
selenium's
特定的等待机制而不是time.sleep()
。这将使您能够更好地微调您的刮刀,也将使其更加可靠。我建议您查看WebDriverWait
其次,我个人的偏好是避免使用
class selectors
。我并不是说他们错了。但经验告诉我,它们可以很容易地改变,而且经常在多个地方使用相同的 class (这就是为什么它是 class )。在这种特殊情况下,选择使用CSS class
是有效的,因为 class 在一个地方使用。如果在下一个版本中,在另一个地方使用相同的 class 会怎样?
虽然也不能保证遵循结构,但更改的可能性较小。
使用
Chrome
。由于版本59
,Google Chrome 有一个headless
选项。在我看来,使用 thenFirefox
要容易得多。使用Firefox
将需要您在生产机器上安装 运行 一个x server
服务,并通过geckodriver
将Firefox
实例连接到该服务器。您可以使用Chrome
. 跳过所有这些
希望对您有所帮助!