本文档由脑图导出,地址:Spider脑图
参考:heima
[TOC]
Spider
爬虫原理与数据抓取
基本概念
通用爬虫和聚焦爬虫
HTTP和HTTPS
str和bytes的区别
Requests库
python
1 | # requests简单实用 |
贴吧爬虫
python
1 | # 功能:爬贴吧数据,存n页的html内容 |
发送post请求
使用代理
python
1 | # 使用代理ip爬虫 |
模拟登陆
python
1 | # 登录人人网 |
保存图片
python
1 | # 保存图片(二进制文件) |
requests的小技巧
python
1 | """note |
chrome抓包的技巧
爬虫数据提取
数据的分类
- 结构化数据
- 处理方法:正则、xpath
- 非结构化数据
- 处理方法:转化为python数据类型
json数据处理
类型转化
如何找到json的url
使用手机版
提取方法
python数据类型 = json.loads(json字符串)
json字符串 = json.dumps(python数据类型)
python数据类型 = json.loads(包含json的类文件对象)
json字符串 = json.dumps(python数据类型)
ps: 具有read()或者write()方法的对象就是类文件对象
f = open(“a.txt”,”r”) f就是类文件对象
demo
python1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33import json
from parse_url import parse_url
from pprint import pprint
url = "https://m.douban.com/rexxar/api/v2/subject_collection/movie_showing/items?start=0&count=18&loc_id=108288"
html_str = parse_url(url)
# json.loads把json字符串转化为python类型
ret1 = json.loads(html_str)
# pprint(ret1) # 格式化输出
# print(type(ret1))
# json.dumps能够把python类型转化为json字符串
with open("douban.json","w",encoding="utf-8") as f:
# ensure_ascii 中文编码 indent 格式化json 4个空格
f.write(json.dumps(ret1,ensure_ascii=False,indent=4))
# f.write(str(ret1))
# with open("douban.json","r",encoding="utf-8") as f:
# ret2 = f.read()
# ret3 = json.loads(ret2)
# print(ret3)
# print(type(ret3))
# 使用json.load提取类文件对象中的数据
with open("douban.json","r",encoding="utf-8") as f:
ret4 = json.load(f)
print(ret4)
print(type(ret4))
#json.dump能够把python类型放入类文件对象中
with open("douban1.json","w",encoding="utf-8") as f:
json.dump(ret1,f,ensure_ascii=False,indent=2)
正则过滤获取json
python
1 | import re |
正则处理数据
正则表达式基础
案例-豆瓣小组爬虫
python
1 | # 爬豆瓣某小组的讨论 title |
xpath处理数据
xpath
获取某贴吧的 标题 url 图片
chrome工具:xpath helper
常用语法:
获取文本
a/text()
获取属性a/@href
当前目录/.
上一级/..
不考虑位置//ul[@id="detail-list"]/li
选列表中某一个
第一个//div[@id='page']/a[1]
最后一个//div[@id='page']/a[last()]
倒数第2个//div[@id='page']/a[last()-1]
前3个//div[@id='page']/a[position<4]
任意节点
//*[id='page']
//node()[id='page']
或|
//div[@id='page']/a[1] | //div[@id='page']/a[3]包含
class包含i的div `//div[contains(@class,'i')]`
lxml
lxml
能自动修正格式不规范的html代码
demo
python1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40# coding=utf-8
from lxml import etree
text = ''' <div> <ul>
<li class="item-1"><a>first item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a>
</ul> </div> '''
html = etree.HTML(text)
print(html)
#查看element对象中包含的字符串
# print(etree.tostring(html).decode())
#获取class为item-1 li下的a的herf
ret1 = html.xpath("//li[@class='item-1']/a/@href")
print(ret1)
#获取class为item-1 li下的a的文本
ret2 = html.xpath("//li[@class='item-1']/a/text()")
print(ret2)
#每个li是一条新闻,把url和文本组成字典
for href in ret1:
item = {}
item["href"] = href
item["title"] = ret2[ret1.index(href)]
print(item)
print("*"*100)
#分组,根据li标签进行分组,对每一组继续写xpath
ret3 = html.xpath("//li[@class='item-1']")
print(ret3)
for i in ret3:
item= {}
item["title"] = i.xpath("a/text()")[0] if len(i.xpath("./a/text()"))>0 else None
item["href"] = i.xpath("./a/@href")[0] if len( i.xpath("./a/@href"))>0 else None
print(item)用xpath改进豆瓣小组爬虫
python1
2
3
4
5
6def get_content_list(self, html_str):
# 变成对象
html = etree.HTML(html_str)
title_list = html.xpath("//table[@class='olt']//tr/td/a/@title")
return title_list
通用爬虫案例
案例
贴吧爬虫
- 保存 每条贴吧的 title\ url\ 每条贴吧里所有img的url
- demo :略
糗百爬虫
- demo:略
爬虫思路总结
实现爬虫的套路
准备url
- 准备start_url
- url地址规律不明显,总数不确定
- 通过代码提取下一页的url
- xpath
- 寻找url地址,部分参数在当前的响应中(比如,当前页码数和总的页码数在当前的响应中)
- 准备url_list
- 页码总数明确
- url地址规律明显
- 准备start_url
发送请求,获取响应
- 添加随机的User-Agent,反反爬虫
- 添加随机的代理ip,反反爬虫
- 在对方判断出我们是爬虫之后,应该添加更多的headers字段,包括cookie
- cookie的处理可以使用session来解决
- 准备一堆能用的cookie,组成cookie池
- 如果不登录
- 准备刚开始能够成功请求对方网站的cookie,即接收对方网站设置在response的cookie
- 下一次请求的时候,使用之前的列表中的cookie来请求
- 如果登录
- 准备多个账号
- 使用程序获取每个账号的cookie
- 之后请求登录之后才能访问的网站随机的选择cookie
- 如果不登录
提取数据
确定数据的位置
如果数据在当前的url地址中
- 提取的是列表页的数据
- 直接请求列表页的url地址,不用进入详情页
- 提取的是详情页的数据
- 确定url
- 发送请求
- 提取数据
- 返回
- 提取的是列表页的数据
如果数据不在当前的url地址中
- 在其他的响应中,寻找数据的位置
- 从network中从上往下找
- 使用chrome中的过滤条件,选择出了js,css,img之外的按钮
- 使用chrome的search all file,搜索数字和英文
- 在其他的响应中,寻找数据的位置
数据的提取
- xpath,从html中提取整块的数据,先分组,之后每一组再提取
- re,提取max_time,price,html中的json字符串
- json
保存
- 保存在本地,text,json,csv
- 保存在数据库
多线程爬虫
python
1 | # 爬10页豆瓣某小组的内容,使用多线程 |



