目录
- 1 介绍
- 2 爬虫代码及其详细解释
- 3 代码运行结果
- 4 总结
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的知识还很多,希望本例能起到抛转引玉的结果,促进大家对相关知识的理解和技能的提高。也希望大家在程序的编写过程中能找到自己的兴奋点,以更强烈的兴趣去进一步的学习。
- Katharine J., Richard L. Python Web Scraping: fetching data from web. 2nd Edition. Packt Publishing, 2017. ↩︎