目录
Requests 访问页面
XPath 定位
JSON 对象
如何使用 XPath 自动下载百度图片
Selenium 库模拟浏览器
Requests 访问页面
Requests 是 Python HTTP 的客户端库,编写爬虫的时候都会用到,编写起来也很简单。它有两种访问方式:Get 和 Post。这两者最直观的区别就是:Get 把参数包含在 url 中,而 Post 通过 request body 来传递参数。
假设我们想访问豆瓣,那么用 Get 访问的话,代码可以写成下面这样的:
r = requests.get('http://https://image.baidu.com/')
代码里的“r”就是 Get 请求后的访问结果,然后我们可以使用 r.text 或 r.content 来获取 HTML 的正文。
如果我们想要使用 Post 进行表单传递,代码就可以这样写:
r = requests.post('http://xxx.com', data = {'key':'value'})
这里 data 就是传递的表单参数,data 的数据类型是个字典的结构,采用 key 和 value 的方式进行存储。
XPath 定位
XPath 是 XML 的路径语言,实际上是通过元素和属性进行导航,帮我们定位位置。它有几种常用的路径表达方式。
我来给你简单举一些例子:
-
xpath(‘node’) 选取了 node 节点的所有子节点;
-
xpath(’/div’) 从根节点上选取 div 节点;
-
xpath(’//div’) 选取所有的 div 节点;
-
xpath(’./div’) 选取当前节点下的 div 节点;
-
xpath(’…’) 回到上一个节点;
-
xpath(’//@id’) 选取所有的 id 属性;
-
xpath(’//book[@id]’) 选取所有拥有名为 id 的属性的 book 元素;
-
xpath(’//book[@id=“abc”]’) 选取所有 book 元素,且这些 book 元素拥有 id= "abc"的属性;
-
xpath(’//book/title | //book/price’) 选取 book 元素的所有 title 和 price 元素。
上面我只是列举了 XPath 的部分应用,XPath 的选择功能非常强大,它可以提供超过 100 个内建函数,来做匹配。我们想要定位的节点,几乎都可以使用 XPath 来选择。
使用 XPath 定位,你会用到 Python 的一个解析库 lxml。这个库的解析效率非常高,使用起来也很简便,只需要调用 HTML 解析命令即可,然后再对 HTML 进行 XPath 函数的调用。
比如我们想要定位到 HTML 中的所有列表项目,可以采用下面这段代码。
from lxml import etree
html = etree.HTML(html)
result = html.xpath('//li')
JSON 对象
JSON 是一种轻量级的交互方式,在 Python 中有 JSON 库,可以让我们将 Python 对象和 JSON 对象进行转换。为什么要转换呢?原因也很简单。将 JSON 对象转换成为 Python 对象,我们对数据进行解析就更方便了。
这是一段将 JSON 格式转换成 Python 对象的代码,你可以自己运行下这个程序的结果。
import json
jsonData = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
input = json.loads(jsonData)
print input
如何使用 XPath 自动下载百度图片
如果你遇到 JSON 的数据格式,那么恭喜你,数据结构很清爽,通过 Python 的 JSON 库就可以解析。但有时候,网页会用 JS 请求数据,那么只有 JS 都加载完之后,我们才能获取完整的 HTML 文件。XPath 可以不受加载的限制,帮我们定位想要的元素。
JSON 数据格式
# coding:utf-8
import requests
import json
query = '王祖贤'
''' 下载图片 '''
def download(src, id):
dir = './' + str(id) + '.jpg'
try:
pic = requests.get(src, timeout=10)
fp = open(dir, 'wb')
fp.write(pic.content)
fp.close()
except requests.exceptions.ConnectionError:
print('图片无法下载')
''' for 循环 请求全部的 url '''
for i in range(0, 22471, 20):
url = 'https://www.douban.com/j/search_photo?q='+query+'&limit=20&start='+str(i)
html = requests.get(url).text # 得到返回结果
response = json.loads(html,encoding='utf-8') # 将 JSON 格式转换成 Python 对象
for image in response['images']:
print(image['src']) # 查看当前下载的图片网址
download(image['src'], image['id']) # 下载一张图片
HTML数据格式
import requests as requests
from lxml import etree
import base64
def download(src, id):
try:
if src.startswith('data'):
#base64数据格式 data:image/png;base64
index = src.index("/")
suffix = src[index+1:index+4] +"."
dir = './' + str(id) + suffix
request_base64=''' '''
imgdata = base64.b64decode(request_base64)
with open(dir, 'wb') as fh:
fh.write(imgdata)
else:
suffix = src[src.rindex("."):len(src)]
dir = './' + str(id) + suffix
pic = requests.get(src, timeout=10)
fp = open(dir, 'wb')
fp.write(pic.content)
fp.close()
except requests.exceptions.ConnectionError:
print('图片无法下载')
if __name__ == '__main__':
url = 'https://image.baidu.com/'
html = requests.get(url).text
# 得到返回结果
response = etree.HTML(html)
results = response.xpath('//img/@src')
i = 0
for url in results:
if url:
print(url) # 查看当前下载的图片网址
download(url, i ) # 下载一张图片
i+=1
Selenium 库模拟浏览器
在 Python 中,这个工具就是 Selenium 库,使用方法如下:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get(request_url)
Selenium 是 Web 应用的测试工具,可以直接运行在浏览器中,它的原理是模拟用户在进行操作,支持当前多种主流的浏览器。
这里我们模拟 Chrome 浏览器的页面访问。
你需要先引用 Selenium 中的 WebDriver 库。WebDriver 实际上就是 Selenium 2,是一种用于 Web 应用程序的自动测试工具,提供了一套友好的 API,方便我们进行操作。
Python + Selenium + 第三方浏览器可以让我们处理多种复杂场景,包括网页动态加载、JS 响应、Post 表单等。因为 Selenium 模拟的就是一个真实的用户的操作行为,就不用担心 cookie 追踪和隐藏字段的干扰了。