[译] 30 分钟 Python 爬虫教程

一直想用 Python 和 Selenium 写一个网页爬虫,但一直都没去实现。直到几天前我才决定动手实现它。写代码从 Unsplash 网站上抓取一些漂亮的图片,这看起来好像是很是艰巨的事情,但实际上倒是极其简单。css

图片来源:Blake Connally 发布于 Unsplash.comhtml

简单图片爬虫的原料

简单图片爬虫的菜谱

以上的全部都安装好了?棒!在咱们继续开始写代码前,我先来解释一下以上这些原料都是用来干什么的。前端

咱们首先要作的是利用 Selenium webdrivergeckodriver 来为咱们打开一个浏览器窗口。首先,在 Pycharm 中新建一个项目,根据你的操做系统下载最新版的 geckodriver,将其解压并把 geckodriver 文件拖到项目文件夹中。Geckodriver 本质上就是一个能让 Selenium 控制 Firefox 的工具,所以咱们的项目须要它来让浏览器帮咱们作一些事。python

接下来咱们要作的事就是从 Selenium 中导入 webdriver 到咱们的代码中,而后链接到咱们想爬取的 URL 地址。说作就作:android

from selenium import webdriver
# 咱们想要浏览的 URL 连接
url = "https://unsplash.com"
# 使用 Selenium 的 webdriver 来打开这个页面
driver = webdriver.Firefox(executable_path=r'geckodriver.exe')
driver.get(url)
复制代码

打开浏览器窗口到指定的 URL。ios

一个远程控制的 Firefox 窗口。git

至关容易对吧?若是以上所说你都正确完成了,你已经攻克了最难的那部分了,此时你应该看到一个相似于以上图片所示的浏览器窗口。github

接下来咱们就应该向下滚动以便更多的图片能够加载出来,而后咱们才可以将它们下载下来。咱们还想再等几秒钟,以便万一网络链接太慢了致使图片没有彻底加载出来。因为 Unsplash 网站是使用 React 构建的,等个 5 秒钟彷佛已经足够”慷慨”了,那就使用 Python 的 time 包等个 5 秒吧,咱们还要使用一些 Javascript 代码来滚动网页——咱们将会用到 [window.scrollTo()](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo) 函数来实现这个功能。将以上所说的合并起来,最终你的代码应该像这样:web

import time
from selenium import webdriver

url = "https://unsplash.com"

driver = webdriver.Firefox(executable_path=r'geckodriver.exe')
driver.get(url)
# 向下滚动页面而且等待 5 秒钟
driver.execute_script("window.scrollTo(0,1000);")
time.sleep(5)
复制代码

滚动页面并等待 5 秒钟。网页爬虫

测试完以上代码后,你应该会看到浏览器的页面稍微往下滚动了一些。下一步咱们要作的就是找到咱们要下载的那些图片。在探索了一番 React 生成的代码以后,我发现了咱们可使用一个 CSS 选择器来定位到网页上画廊的图片。网页上的布局和代码在之后可能会发生改变,但目前咱们可使用 #gridMulti img 选择器来得到屏幕上可见的全部 <img> 元素。

咱们能够经过 [find_elements_by_css_selector()](http://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.find_element_by_css_selector) 获得这些元素的一个列表,但咱们想要的是这些元素的 src 属性。咱们能够遍历这个列表并一一抽取出 src 来:

import time
from selenium import webdriver

url = "https://unsplash.com"

driver = webdriver.Firefox(executable_path=r'geckodriver.exe')
driver.get(url)

driver.execute_script("window.scrollTo(0,1000);")
time.sleep(5)
# 选择图片元素并打印出他们的 URL
image_elements = driver.find_elements_by_css_selector("#gridMulti img")
for image_element in image_elements:
    image_url = image_element.get_attribute("src")
    print(image_url)
复制代码

选择图片元素并得到图片 URL。

如今为了真正得到咱们找到的图片,咱们会使用 requests 库和 PIL 的部分功能,也就是 Image。咱们还会用到 io 库里面的 BytesIO 来将图片写到文件夹 ./images/ 中(在项目文件夹中建立)。如今把这些都一块儿作了,咱们要先往每张图片的 URL 连接发送一个 HTTP GET 请求,而后使用 ImageBytesIO 来将返回的图片存储起来。如下是实现这个功能的其中一种方式:

import requests
import time
from selenium import webdriver
from PIL import Image
from io import BytesIO

url = "https://unsplash.com"

driver = webdriver.Firefox(executable_path=r'geckodriver.exe')
driver.get(url)

driver.execute_script("window.scrollTo(0,1000);")
time.sleep(5)
image_elements = driver.find_elements_by_css_selector("#gridMulti img")
i = 0

for image_element in image_elements:
    image_url = image_element.get_attribute("src")
    # 发送一个 HTTP GET 请求,从响应内容中得到图片并将其存储
    image_object = requests.get(image_url)
    image = Image.open(BytesIO(image_object.content))
    image.save("./images/image" + str(i) + "." + image.format, image.format)
    i += 1
复制代码

下载图片。

这就是爬取一堆图片所须要作的全部了。很显然的是,除非你想随便找些图片素材来作个设计原型,不然这个小小的爬虫用处可能不是很大。因此我花了点时间来优化它,加了些功能:

  • 容许用户经过指定一个命令行参数来指定搜索查询,还有一个数值参数指定向下滚动次数,这使得页面能够显示更多的图片可供咱们下载。
  • 能够自定义的 CSS 选择器。
  • 基于搜索查询关键字的自定义结果文件夹
  • 经过截断图片的预览图连接来得到全高清图片
  • 基于图片的 URL 给图片文件命名。
  • 爬取最终结束后关闭浏览器。

你能够(你也应该)尝试本身实现这些功能。全功能版本的爬虫能够在这里下载。记得要先按照文章开头所说的,下载 geckodriver 而后链接到你的项目中。


不足之处,注意事项和将来优化项

整个项目是一个简单的“验证概念”,以弄清楚网页爬虫是如何作的,这也就意味着有不少东西能够作,来优化这个小工具:

  • 没有致谢图片最开始的上传者是个很很差的作法。Selenium 确定是有能力处理这种状况的,那么每一个图片都带有做者的名字。
  • Geckodriver 不该该被放在项目文件夹中,而是安装在全局环境下,并被放到 PATH 系统变量中。
  • 搜索功能能够轻易地扩展到多个查询关键字,那么下载不少类型图片地过程就能够被简化了。
  • 默认浏览器能够用 Chrome 替代 Firefox,甚至能够用 PhantomJS 替代,这对这种类型的项目来讲是更好的。

掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索