python操作流程及爬取豆瓣图片
常见的数据来源
类别 | 解释 | 例子 |
---|---|---|
开放数据源 | 重要是行业数据库,政府公开的各类数据 | 国家统计局、wind、巨潮资讯网 |
爬虫爬取的数据 | 通过爬虫取得的数据 | 豆瓣、社交网站、电商网站、图片网站 |
传感器采集 | 通过传感器采集到的数据 | |
日志采集 | 应用埋点采集到的数据 |
爬取数据的工具
火车采集器。 可以做抓取工具,也可以做数据清洗、数据分析、数据挖掘和可视化等工作。
八爪鱼。 可以实现自动云采集。
集搜客。 缺点是没有云采集功能,所有爬虫都是在用户自己电脑上跑的。
爬虫的操作流程
爬虫模拟我们日常获取网页信息的流程,通过计算机程序自动化爬取内容。
包括三个阶段:
- 打开网页。工具为Requests ,数据包括 HTML 页面以及 JSON 数据。
- 爬取数据。针对HTML页面使用XPath 提取数据,针对JSON数据使用JSON 库进行解析。
- 保存数据。可以使用Pandas 保存数据,导出为CSV 文件。
三个阶段解析
Requests
Requests有两种访问方式,Get和Post。
其中Get把参数包含在链接中。
1
|
r = requests.get('http://www.douban.com')
—|—
Post通过request body传递参数。
1
|
r = requests.post('http://xxx.com', data = {'key', 'value'})
—|—
data的数据结构是字典,通过key 和 value 对数据储存。
动态数据需要通过XHR发出HTTP请求。
Xpath
XPath 是 XML 的路径语言,帮助定位位置。
使用Xpath解析规则
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。
表达式 | 描述 |
---|---|
node | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 选取所有的当前节点,不考虑位置 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
| | 或,两个节点的合并 |
text() | 当前路径下的文版内容 |
下面用这个网站上的例子举例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
—|—
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang=’eng’] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
xpath(’//@id’) 选取所有的 id 属性;
xpath(’//book[@id]’) 选取所有拥有名为 id 的属性的 book 元素;
xpath(’//book[@id=“abc”]’) 选取所有 book 元素,且这些 book 元素拥有 id= “abc”的属性;
xpath(’//book/title | //book/price’) 选取 book 元素的所有 title 和 price 元素。
定位到所有列表项目,需要使用lxml,下面代码为定位到HTML所有列表函数。
1
2
3
|
from lxml import etree
html = etree.HTML(html)
result = html.xpath('//li')
—|—
JSON
Json.dumps():将python对象转换成ISON对象。
Json.load():将python对象转换成JSON对象。
1
2
3
4
5
6
7
|
import json
jsonData = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
input = json.loads(jsonData)
print(input)
—|—
输出结果为:
1
|
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
—|—
项目实战:爬取葛优相关图片
步骤一:打开网页
打开豆瓣图片,输入关键词葛优
步骤二:选择图片
在搜索结果中,可以看到网页是动态的(即往下滑可以看到更多的图片),动态数据需要通过XHR发出HTTP请求,此处需要知道JSON。
我们先来寻找XHR结构,方法是通过:1)谷歌浏览器右键单击检查;2)选择Network;3)选择XHR;4)刷新页面。从图片中可以看到共有1724张葛优相关的图片。
从上图最下面的方框中可以看到JSON。可以看到数据被放到images里面,每张图片通过字典形式储存,元数据包含author、height、id、src、title、width等信息,有了这些信息,我们便可以提取需要的数据。
在看一下图片的组成,limit:20,最大可以显示20张,第一张图片从0开始,我们便可以写个for循环实现所有的下载。
1
2
3
4
5
6
7
8
9
10
11
12
|
images: [{src: "https://img3.doubanio.com/view/photo/photo/public/p399074242.jpg", author: "饭",…},…]
0: {src: "https://img3.doubanio.com/view/photo/photo/public/p399074242.jpg", author: "饭",…}
author: "饭"
height: 600
id: "399074242"
src: "https://img3.doubanio.com/view/photo/photo/public/p399074242.jpg"
title: "葛优"
url: "https://www.douban.com/link2/?url=http%3A%2F%2Fwww.douban.com%2Fphotos%2Fphoto%2F399074242%2F&query=%E8%91%9B%E4%BC%98&cat_id=1025&type=search"
width: 414
limit: 20
more: true
total: 1724
—|—
提取需要的信息
找到了网页及所需要的信息,接下里就是提取所需要的数据,并且进行储存。
完整代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# -*- 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, 1723, 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']) # 下载一张图片
—|—
参考资料
ChangeLog
20201029 补充Xpath案例,仍然出现错误Expecting value: line 1 column 1 (char 0)
20200901 爬虫代码运行错误