27

Python爬虫很强大,在爬虫里如何自动操控浏览器呢?

 4 years ago
source link: https://www.tuicool.com/articles/IzERjye
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

概述:

python通过selenium爬取数据是很多突破封锁的有效途径。但在使用selenium中会遇到很多问题,本文就通过一问一答的形式来通熟易懂的普及如何通过selenium执行javascript程序,进而获取动态执行后的网页。如果你喜欢,欢迎转发本文。

UFVnQz3.jpg!web

python爬虫编程:用selenium执行javascript出错了,该咋改?

问题:

小明开始学习python爬虫编程了,仿佛整个互联网的数据都快被他纳入囊中了。今天,他又试图完成一个高难度动作,他想让selenium中抓取到以下HTML后,并自动执行js脚本,模仿鼠标自动执行一个点击动作。但令他很失望的是,居然,居然,没用!

<div class="vbseo_liked"> 
<a href="http://www.jamiiforums.com/member.php?u=8355" rel="nofollow">Nyaralego</a> 
, 
<a href="http://www.jamiiforums.com/member.php?u=8870" rel="nofollow">Sikonge</a> 
, 
<a href="http://www.jamiiforums.com/member.php?u=8979" rel="nofollow">Ab-Titchaz</a> 
and 
<a onclick="return vbseoui.others_click(this)" href="http://www.jamiiforums.com/kenyan-news/225589-kenyan-and-tanzanian-surburbs.html#">11 others</a> 
like this. 
</div> 

这是他执行的代码。

browser.execute_script("document.getElement(By.xpath(\"//div[@class='vbseo_liked']/a[contains(@onclick, 'return vbseoui.others_click(this)')]\").click()") 

它没用,没有反应。究竟做错了什么?

Python大大的答案:

要点回答:

使用selenium查找元素并将其传递execute_script()给单击:

link = browser.find_element_by_xpath('//div[@class="vbseo_liked"]/a[contains(@onclick, "return vbseoui.others_click(this)")]') 
browser.execute_script('arguments[0].click();', link) 

如果要从头解决这问题,那么以下就是需要了解它的一系列事情:

  • 如何使用JavaScript模拟点击?

这就是我做的东西。这很简单,但它有效:

function eventFire(el, etype){ 
 if (el.fireEvent) { 
 el.fireEvent('on' + etype); 
 } else { 
 var evObj = document.createEvent('Events'); 
 evObj.initEvent(etype, true, false); 
 el.dispatchEvent(evObj); 
 } 
} 

用法:

eventFire(document.getElementById('mytest1'), 'click'); 
  • 如何在Python里进行模拟点击呢?首先制定一个自定义的预期条件,等待元素被“执行”:
class wait_for_text_not_to_end_with(object): 
 def __init__(self, locator, text): 
 self.locator = locator 
 self.text = text 
 def __call__(self, driver): 
 try : 
 element_text = EC._find_element(driver, self.locator).text.strip() 
 return not element_text.endswith(self.text) 
 except StaleElementReferenceException: 
 return False 

定义完毕后,如何在程序里调用这个类呢?看看以下代码:

from selenium import webdriver 
from selenium.common.exceptions import StaleElementReferenceException 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 
class wait_for_text_not_to_end_with(object): 
 def __init__(self, locator, text): 
 self.locator = locator 
 self.text = text 
 def __call__(self, driver): 
 try : 
 element_text = EC._find_element(driver, self.locator).text.strip() 
 return not element_text.endswith(self.text) 
 except StaleElementReferenceException: 
 return False 
browser = webdriver.PhantomJS() 
browser.maximize_window() 
browser.get("http://www.jamiiforums.com/kenyan-news/225589-kenyan-and-tanzanian-surburbs.html") 
username = browser.find_element_by_id("navbar_username") 
password = browser.find_element_by_name("vb_login_password_hint") 
username.send_keys("MarioP") 
password.send_keys("codeswitching") 
browser.find_element_by_class_name("loginbutton").click() 
wait = WebDriverWait(browser, 30) 
wait.until(EC.visibility_of_element_located((By.XPATH, '//h2[contains(., "Redirecting")]'))) 
wait.until(EC.title_contains('Kenyan & Tanzanian')) 
wait.until(EC.visibility_of_element_located((By.ID, 'postlist'))) 
# click "11 others" link 
link = browser.find_element_by_xpath('//div[@class="vbseo_liked"]/a[contains(@onclick, "return vbseoui.others_click(this)")]') 
link.click() 
browser.execute_script(""" 
function eventFire(el, etype){ 
 if (el.fireEvent) { 
 el.fireEvent('on' + etype); 
 } else { 
 var evObj = document.createEvent('Events'); 
 evObj.initEvent(etype, true, false); 
 el.dispatchEvent(evObj); 
 } 
} 
eventFire(arguments[0], "click"); 
""", link) 
# wait for the "div" not to end with "11 others link this." 
wait.until(wait_for_text_not_to_end_with((By.CLASS_NAME, 'vbseo_liked'), "11 others like this.")) 
print 'success!!' 
browser.close() 

看,如何在python里通过selenium来爬取数据就是这么简单。要点掌握好,开始编制自己的爬虫吧。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK