网络数据采集 ----> 爬虫(蜘蛛)(1)
1.基本知识
中小企业是很缺乏数据,要么选择购买数据,要么选择爬虫采集数据
1. 怎么写爬虫程序?
~ 获取页面的代码 ---> HTML ---> 数据放在HTML标签中
~ 解析HTML页面 ---> 正则表达式 / XPath / CSS选择器
~ 数据的持久化 ---> 文本文件(CVS)/ Excel / 数据库
2. 写爬虫程序违法吗?
~ 灰色地带 ---> 法不禁止即为许可
~ 如果被目标网站举证你有破坏别人动产的行为,打官司基本败诉
~ 遵循爬虫协议 ---> robots.txt
~ 如果不想遵守爬虫协议 ---> 隐匿自己的身份(让目标网站感觉不到你是一个爬虫程序,而是一个来自浏览器的正常请求)
3. 爬虫的分类:
~ 通用爬虫
~ 定向爬虫(只关注某领域的数据)
4. HTML
~ Hyper-Text Markup Language -----> 超文本标签语言
~ 浏览器就是HTML语言的解释器,它能够执行HTML书写的代码
~ HTML页面最核心的就是标签,除了标签之外,还有CSS和JavaScript
网页的头目 ![在这里插入图片描述]()
HTML = Tag(标签)+ CSS(层叠样式表)+ JavaScript(JS)
Tag ----> 数据(content)
CSS ----> 显示(display) —> 选择器(负责页面渲染)
JS ----> 行为(behavior) —> 代码(交互式行为)
练习: 获取搜狐首页HTML代码
1.requests ------>基于HTTP(S)协议联网的三方库
加载方式:在pycharm中打开终端Terminal输入
pip config set global.index-url https://pypi.doubanio.com/simple
给pip改配置,改成国内的豆瓣镜像。再输入pip install requests安装requests
import requests
resp = requests.get('https://www.sohu.com:443/index.html')
print(type(resp), resp.status_code)
# <class 'requests.models.Response'> 200
# response对象,服务器返回的响应对象
"""
response对象有个属性是content可以获取页面二进制的内容
"""
print(resp.text)
# 直接获取返回的文本内容
print(resp.contect.decode('utf-8'))
# 如果直接获取resp.text有乱码的话可以解码字节串
# 有些网站是压缩过的,占空间更小,传输更快
str --------> 字符串 --------> encode() ------->bytes
bytes -------> 字节串 --------->decode() --------> str
5.URL和URI
~ URI ---> 统一资源标识符 ---> Universal Resource Identifier ---> 网络上的一个资源的唯一标识
~ URI ---> URL + URN(唯一标识举例:urn:isbn:978-7-5596-0344-9)
~ URL ---> 网址 ---> Uniform Resource Locator ---> 统一资源定位符
一个完整的URL
https://username:password@www.sohu.com:443/path1/path2/index.html 协议://用户名:口令@主机(服务器域名或IP地址):端口号/路径/子路径/资源名称
import requests
resp = requests.get('https://www.sohu.com:443/index.html')
print(type(resp), resp.status_code)
print(resp.text)
获取百度的LOGO
import requests
resp = requests.get('https://www.baidu.com/img/PCpad_012830ebaa7e4379ce9a9ed1b71f7507.png')
print(resp.content)# 结果就是图片的二进制数据
with.open('baidu_logo.png', 'wb') as file:
file.write(resp.content)
# 图片不是纯文本的,图片是二进制文件
6. HTTP —> 超文本传输协议
import requests
resp = requests.get('https://www.sohu.com:443/index.html')
print(type(resp), resp.status_code)
# resp.status响应状态码为 200,则可以访问
~ 请求
\- 请求行:请求方式 请求路径 协议版本
\- 请求头:键值对
~ Host ---> 请求的主机
~ Accept ---> 接受的内容类型
~ User-Agent ---> 操作系统和浏览器平台 ---> 如果爬虫要伪装成浏览器,就需要设置该项
~ Accept-Language ---> 浏览器的语言设定
~ Accept-Encoding ---> 编码和压缩方式
\- 空行
\- 消息体:浏览器要发给服务器的数据
~ 响应
\- 响应行:协议版本 响应状态码
~ 2xx:成功
~ 3xx:重定向
~ 4xx:请求有问题
\- 404:Not Found ---> 找不到对应的资源
\- 401:Unauthorized ---> 未授权
\- 403:Forbidden ---> 禁用(没有权限)
\- 405:Method not Allowd ---> 请求的方式不对
\- 418:I am a tea pot ---> 服务器给不了你想要的内容
~ 5xx:服务器卵了
\- 响应头:键值对!
\- 空行
\- 消息体:服务器给浏览器的内容 ---> (如果请求的是网页,消息体里面就是HTML代码;如果请求的是图片,消息体里面就是图片的二进制数据)
7. HTTPS
~ HTTP over SSL —> 安全的HTTP
获取搜狐首页
import re
import requests
pattern = re.compile(r'\<a\s+.*?href=\"(.+?)" .*?title=[\'\"](.+?)[\'\"]\>')
resp = requests.get(
url='https://www.sohu.com/',
headers={ # headers请求头
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/88.0.4324.190 Safari/537.36'
}
)
print(resp.status_code)
print(resp.text)
获取豆瓣电影Top250电影名称
法一:正则表达式
import re
import time
import random
import requests
# 正则表达式的捕获组:捕获电影标题
pattern = re.compile(r'\<span class="title"\>(.+?)\<\/span\>')
for page in range(10):
resp = requests.get(
url='https://movie.douban.com/top250?start={page * 25}/',
# 参数名=参数值,获取25页
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko)'
'Chrome/88.0.4324.190 Safari/537.36'
# 字符串太长为了美观可以折行,折行注意空格不能变少了
}
)
print(resp.status_code)
movie_titles = pattern.findall(resp.text)
for title in movie_titles:
print(title)
time.sleep(random.randint(3, 5))
# 随机休眠3-5秒