利用Selenium配合Chromedriver爬取一个带输入框、选择框和提交按钮的基于AJAX的网页

1 介绍

阅读书籍《Python Web Scraping: fetching data from web》1第二版的113页例子时,心情激动,被Selenium的功能所吸引,遂写此博文加以总结。该书上例子直接运行会出错,因为其针对的网页网址已变动。本博文给出的例子已进行相关的修正,那么本博文相比较该书的例子有哪些特色呢?包含以下几点:

  • 修正了要爬取的网页的网址。这是正确爬虫的关键。
  • 使用的第三方浏览器Chromedriver,因为在Windows操作系统下广泛使用的浏览器是Chrome,方便我们配合着Chrome浏览器进行相关的调试。
  • 配合着Chrome浏览器的开发者工具(developer tool),详细给出对相关标签的定位,给出返回结果相关标签的定位(这一点很重要,因为我们利用通常的爬虫手段、或者直接查看网页的源代码都看不到)。

待爬取的网页地址为:
http://example.webscraping.com/places/default/search
该网页基于AJAX技术,里面使用JavaScript代码,采用通常的爬虫技术爬不出任何结果。因此,以该网页为例讲解Selenium技术的应用是有趣的和必要的。

爬取该网页的代码虽然简短,但涉及到的知识和技能比较多。需要我们善于学习和勤于思考。爬取该网页涉及到:

  • 文本框模拟输入
  • 选择输入框值填充
  • 提交按钮的模拟点击
  • 查询返回值标签元素的定位
  • 当然,也少不了Css Selector方面的知识

听了上面的介绍,是不是很激动。我已经按捺不住激动的心情了。

2 爬虫代码及其详细解释

# scrapeJavaScriptSearch.py
# Author: Guangzhi Chen
# Date: 2020-08-24
# for book Python web Scraping: fetching data from Web, 2ed. 2017.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()

chrome_options.add_argument("--headless")
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(
    executable_path='drivers/chromedriver', 
    options=chrome_options)
driver.get('http://example.webscraping.com/places/default/search')

driver.find_element_by_id('search_term').send_keys('.')
js = "document.getElementById('page_size').options[1].text = '1000';"
driver.execute_script(js)
driver.find_element_by_id('search').click()

driver.implicitly_wait(30)
links = driver.find_elements_by_css_selector('#results a')
countries = [link.text for link in links]

print(countries)
driver.close()

怎样在Python环境下安装Selenium及下载第三方浏览器驱动,在此不介绍了,请参看我的另一篇博文。在此逐行解释主要的代码涵义。

我们先看网页的展现,如下图:
默认打开的网页展现
默认打开时的对应的HTML代码,如下(只给出关心的部分):

<form>
<table>
    <tr>
        <th>Name:</th>
        <td><input id="search_term" /></td>
    </tr>
    <tr>
        <th>Page size:</th>
        <td>
            <select id="page_size">
                <option>4</option>
                <option selected>10</option>
                <option>20</option>
            </select>
        </td>
    </tr>
    <tr>
        <td></td>
        <td>
            <input type="submit" id="search" value="Search" />
        </td>
    </tr>
</table>
</form>

有了HTML代码,并配合着HTML页面展现,我们会很容易理解相应代码的涵义。

代码driver.find_element_by_id('search_term').send_keys('.')的涵义为:根据标签的id查找id值为search_term的标签项,实际上查到的是最上面的文本输入框;然后向该文本输入框输入.,输入的内容是正则表达式,亦即匹配任何字符。

代码

js = "document.getElementById('page_size').options[1].text = '1000';"
driver.execute_script(js)

的涵义为:执行JavaScript代码,JavaScript代码做的事情是,找到选择输入框,并设置该数据框的值为1000,目的要查出所有的结果。

代码driver.find_element_by_id('search').click()的涵义为:找出id值为search的按钮,并点击该按钮。

代码driver.implicitly_wait(30),等待Chromedriver运行30秒,以保证相应的网页JavaScript代码执行完毕。

代码links = driver.find_elements_by_css_selector('#results a')涵义:从返回结果中找出id为results下的所有的标签a。怎样才能写出这样的CSS选择器呢?我们需要利用Chrome的开发者工具得到(需要执行手工查询),在页面上右击结果元素,在出现的快捷菜单上点击Inspect,如下图所示:
返回结果元素定位
通过上图,我们可以清晰地看到,为什么写出这样的CSS选择器表达式#results a

3 代码运行结果

如下图:
运行结果

4 总结

学习要联动起来,综合多方思考。当然,Selenium的知识还很多,希望本例能起到抛转引玉的结果,促进大家对相关知识的理解和技能的提高。也希望大家在程序的编写过程中能找到自己的兴奋点,以更强烈的兴趣去进一步的学习。


  1. Katharine J., Richard L. Python Web Scraping: fetching data from web. 2nd Edition. Packt Publishing, 2017. ↩︎

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页