1、什么是爬虫
所谓爬虫,就是按照一定规则,自动的从网络中抓取信息的程序或者脚本。万维网就像一个巨大的蜘蛛网,我们的爬虫就是上面的蜘蛛,不断的去抓取我们需要的信息。
2、爬虫的基本步骤
- 获取数据
- 解析数据
- 提取数据
- 存储数据
3、网页基本知识
- 每个网页都有自己的URL(统一资源定位符)来定位
- 网页都使用HTML(超文本标记语言)来描述页面信息
- 网页都使用HTTP/HTTPS(超文本传输协议)来传输HTML数据
HTML元素是HTML文档的重要组成部分,一个HTML文档由大量的元素组成。元素嵌套会产生一个树状的层次结构。
![](https://i-blog.csdnimg.cn/blog_migrate/c4f34a28af28d8679f35b162b718ce88.png)
4、浏览器访问机制
- 浏览器向WEB服务器发出了一个HTTP请求(Http Request)
- WEB服务器接收到客户端浏览器的请求
- 响应客户端的请求,发回相应的响应信息(Http Response)
- 浏览器解析引擎,排版引擎分析返回的内容,呈现给用户。
5、使用requests获取网页数据
request是一个用来向网页发送请求的第三方HTTP库。相比起urilib,它的语法更加简洁易懂,能够明显提高编程效率和体验。
安装requests
pip install requests
导入requests库
import requests
发出请求
r = requests.get('https://url-xxx.com')
得到一个Response对象r,这个对象里包含了我们想要的网页信息。
html_info = r.text 获取字符串形式的网页信息
6、Beautiful Soup 好用的网页解析工具
Beautiful Soup简介
Beautiful Soup是Python的一个库,提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。他是一个工具箱,通过解析文档为用户提供需要抓取的数据。
安装Beautiful Soup
pip install beautifulsoup4
创建Beautiful Soup对象
from bs4 import BeautifulSoup
soup = BeautifulSoup(markup)
Beautiful Soup支持的解析器
Beautiful Soup的对象类型
Beautiful Soup将复杂HTML文档转换成一个负载的树形结构,每个节点都是Python对象。所有对象可以归纳为4种:Tag,NavigableString,BeautifulSoup,Comment.
![](https://i-blog.csdnimg.cn/blog_migrate/9f2c03faf015c299b016b41b4b878ca7.png)
Tag对象
Tag对象与XML或HTML原生文档中的tag相同,通俗讲就是HTML中的一个个标签
Tag有两个重要属性,分别是name和attrs
name:Tag的名称
attrs:一个tag可能有很多个属性,属性以字典方式存储
代码实例:
from bs4 import BeautifulSoup
soup = BeautifulSoup('<b class="boldest" id="10010">Extremely bold</b>',"html.parser")
tag = soup.b
print(type(tag))
print(tag.name)
print(tag.attrs)
print(tag.string)
print(type(tag.string))
tag.string.replace_with('hello mychaitc')
print(tag.string)
str_tag = str(tag.string)
print(type(str_tag))
print(type(soup))
print(soup.name)
运行结果:
NavigableString(可以遍历的字符串)
字符串常被包含在tag内。Beautiful Soup用NavigableString类来包装tag中的字符串:
tag.string
type(tag.string)
tag中包含的字符串不能编辑,但是可以被替换成其他的字符串,用replace_with()方法:
tag.string.replace_with('hello mychaitc')
如果想要在Beautiful Soup之外使用Navigable对象,需要使用str()方法,讲该对象转换成普通的字符串
str_tag = str(tag.string)
print(type(str_tag))
BeautifulSoup对象与Comment对象
BeautifulSoup对象
BeautifulSoup对象表示一个文档的全部内容。大部分时候可以把它当作Tag对象,它支持遍历文档树和搜索文档树中描述的大部分的方法。
type(soup)
soup.name
Comment(注释)
markup = "<b><!--Hey,buddy. Want to buy a used parser?--></b>"
soup1 = BeautifulSoup(markup,"html.parser")
comment = soup1.b.string
print(type(comment))
print(comment)
运行结果:
文档树的遍历
子节点:一个Tag可能包含多个字符串或其他的Tag,这些都是Tag的子节点。Beautiful Soup提供了许多操作和遍历子节点的属性。
- 所有子孙节点:.descendants
- 父节点:.parent
- 所有父节点:.parents
- 兄弟节点:.next_sibling和.previous_sibling
- 全部兄弟节点:.next_siblings和.previous_siblings
- 前后节点:.next_element和.previous_element
- 所有前后节点:.next_elements和.previous_elements
注意:复数返回的都是一个迭代序列对象,需要使用for循环迭代输出
文档树的搜索
过滤器:对于搜索内容进行过滤
- 字符串
在搜索方法中传入一个字符串参数,Beautiful Soup会查找与字符串完整匹配的内容。
soup.find_all('b')
- 正则表达式
如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的match()来匹配内容。
soup.find_all(re.compile("^b"))
- 列表
如果传入列表,Beautiful Soup会将与列表中任一元素匹配的内容返回。
soup。find_all(["a","b"])
- True
True可以匹配任何值,但是不会返回字符串节点。
find_all()方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件。
- 查找标签:基于name的参数 item = soup.find_all('ul')
- 查找文本:基于text参数 items = soup.find_all(text = 'plants')
- 基于正则表达式的查找:items = soup.find_all(re.compile("^b"))
- 查找标签的属性:基于attrs参数 items = soup.find_all(id='a')
- 基于函数的查找:自定义函数作为参数
find()方法返回满足过滤器条件的第一个tag子节点
数据存储:爬完的数据怎么保存呢
数据存储的一般方法:
- 文本:txt,excel,csv,Json,Xml等
- 关系型数据库:如mysql,oracle,sql server等结构化数据库
- 非关系型数据库:MongoDB,Redis等key-value形式存储
JSON模块
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,适用于进行数据交换的场景。
Python中自带了json模块,直接用import json即可实现。
json就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构。
- 对象:对象在js中表示{}括起来的内容,数据结构为{key:value,key:value,...}的键值对的结构
- 数组:数组在js中是中括号[]括起来的内容,数据结构为["Python","javascript","C++",...],取值方式和所有语言中一样,使用索引获取。
JSON模块使用
json.dumps()方法实现python类型转换为json字符串,返回一个str对象
json.dump()方法实现python类型转化为json字符串,并写入到json文件中
Python | JSON |
dict | object |
list,tuple | array |
str | string |
int,float,int- & float-derived Enums | number |
True | true |
False | false |
None | null |
代码实例:
import json
a = {'name':'xiaoming','age':7}
c = json.dumps(a)
print(c)
f1 = open('test.json','w')
json.dump(a,f1)
f1.close()
print(type(c))
f2 = open('test.json','r')
d = json.load(f2)
f2.close()
print(d)
print(type(d))
运行结果:
load()和loads()方法实现json字符串转换为python类型
PyMySQL是在Python3.x版本中用于连接MySQL服务器的一个库
连接数据库前,需要确保
已经创建了数据库
在数据库中已经创建了表和对应字段
连接数据库时已经设置用户名和密码
已经安装了pymysql模块
import pymysql
conn = pymysql.connect(
user='root',
password='******',
host='122.****',
port=3306,
database='ownCloud',
use_unicode=True,
charset="utf8"
)
# 获取游标
cursor = conn.cursor()
cursor.execute("select * from oc_jobs;")
result = cursor.fetchall()
print(result)
print(type(result))
# 提交
# conn.commit()
# 关闭连接
cursor.close()
运行结果:
Q&A
Q:关于抓取的页面数据和浏览器里看到的不一样的问题
A:很多网站中的数据都是通过JavaScript动态加载的,所以直接通过get请求获取的页面和浏览器显示的不同。
Q:爬虫入门后,想开展一些具体的工作,应该怎么办呢?
A:如果要进行爬虫实战的话,建议进一步学习一些优秀的框架,比如Scrapy和PySpider等,可以更方便的进行网络爬虫。