14. 手把手教你搭建爬虫程序框架-网络请求
1. 课题导入
有好几个同学给我发消息,说“看了不少、学了不少教程,还是不会写”,“看别人的慢慢能看懂,但自己写就无从下手”,“老师,我记不住各种库名和方法”。
首先,编程是一个孰能生巧的技术活,是不需要特殊记忆的,你敲多了它自然就是你的了。你想敲一遍就让它成为你大脑里的东西,对普通人基本是不现实的。
其次,为了大家能快速上手,我以后会不定期总结一些框架类的笔记给大家。类似一个模板,大家对照模板多实战几次,基本就有感觉了。
最后,Python的每一块知识点都特别细特别广,框架只是一个基础,大家要结合自己的实际选择应用。
【安迪碎碎念】
学编程,重要的就是敲,不断的敲,不断的尝试,不断的报错,不断的修正bug,这就是我学习的方法。
有些问题当下不能理解的,不能解决的,可以先放一放,随着学习的内容越来越深入,以前不能理解的慢慢就能理解了。
例如:我刚开始接触类的相关知识的时候,我看了许多视频来理解类,但还是觉得太抽象,也一直写不出让自己满意的笔记。但我后写了几个爬虫程序、解答了几个学生的作业,我对类又有新的认识,现在算是能理解类的作用了。
所以,有时候当下不能理解的可以先缓一缓,多实操,实操一定是学习的最好途径。
本节的目的是搭建爬虫框架(网络请求部分),但搭建之前我们先来学习一个基础知识。
2. 字符串的切片取值语法
字符串的切片取值是通过指定起始位置和结束位置来获取字符串的一部分。
【语法】
string[start:end]
string
表示要操作的字符串对象。start
表示起始位置。end
表示结束位置。
【温馨提示】
- 切片取值时,起始位置是包含在结果中的,而结束位置是不包含在结果中的。即含前不含后,包含start对应的字符,不包含end对应的字符。
- 如果不指定起始位置,默认为字符串的开头;如果不指定结束位置,默认为字符串的结尾。
- 索引从0开始编码,即字符串的第1个字符索引为0。
string = "12345678"
print(string[0:5]) # 取第1到第5个字符
print(string[7:]) # 取第8个及以后的字符
print(string[:5]) # 取第1个到第5个字符
print(string[-6:]) # -6对应的字符为3,取3以后的字符
【终端输出】
12345
8
12345
345678
3. 发送网络请求框架
【发送网络请求框架注释版】
# 1. 发送网络请求
# requests库,发送网络请求
import requests
# 导入fake_useragent库中的UserAgent类
from fake_useragent import UserAgent
# 实例化UserAgent类创建一个UserAgent对象
# 实例化对象语法:对象 = 类名( )
# ua为对象名
# UserAgen为类名
ua = UserAgent( )
# 调用ua的random方法,获取随机的User-Agent头部信息
# 调用方法语法:对象.方法名( )
# ua对象名
# random方法名
# ua.random随机生成一个User-Agent头部信息
# 构建一个字典
header = {'User-Agent':ua.random}
# 定义请求url
url = 'https://item.jd.com/10072335332864.html'
# 用get方法发送网络请求
# r是变量名,数据类型为Response对象
# requests库名
# get方法名,作用是发送网络请求
# url 要访问的网址
r = requests.get(url)
# 用post方法发送网络请求
# url:请求的URL地址。
# data:请求的数据,可以是字典、元组列表、文件对象等。
# json:请求的JSON数据。
# headers:请求头,可以是字典类型。
# cookies:请求的cookies,可以是字典类型。
# auth:认证信息,可以是元组类型。
# timeout:请求超时时间,单位为秒。
r = requests.post(url, data=None, json=None, headers=None, cookies=None, auth=None, timeout=None)
# 打印服务器返回的响应状态码,查网络请求是否成功
# r为Response对象
# status_code是Response对象的状态码属性,返回200表示网络请求成功
print(r.status_code)
# 2. 查看响应内容
# 将 Response 对象的编码格式设置为 gbk
r.encoding = 'gbk'
r.encoding = 'UTF-8'
# 打印响应内容
# text是Response对象的属性,作用是输出网页源代码,类型为字符串数据
print(r.text)
# [:1000]:表示对字符串进行切片操作,只取前1000个字符
print(r.text[:1000])
# tontent是Response对象的属性,作用是输出网页源代码,类型为二进制数据
print(r.tontent)
# json是Response对象的方法,语法为对象.方法(),作用是输出json数据
print(r.json())
【发送网络请求框架无注释版】
import requests
from fake_useragent import UserAgent
ua = UserAgent( )
header = {'User-Agent':ua.random}
url = 'https://item.jd.com/10072335332864.html'
# 用get方法发送网络请求
r = requests.get(url)
# 用post方法发送网络请求
r = requests.post(url, data=None, json=None, headers=None, cookies=None, auth=None, timeout=None)
# 打印服务器返回的响应状态码,查网络请求是否成功
print(r.status_code)
# 将 Response 对象的编码格式设置为 gbk
r.encoding = 'gbk'
r.encoding = 'UTF-8'
# 打印响应内容
print(r.text)
print(r.text[:1000])
print(r.tontent)
print(r.json())
框架搭好了,下面我们看如何使用。
【使用方法】
- 替换url,将下面的网址替换成你的请求网址。
url = 'https://item.jd.com/10072335332864.html'
- 选择请求方法。根据实际选择get方法或者post方法。
r = requests.get(url)
r = requests.post(url, data=None, json=None, headers=None, cookies=None, auth=None, timeout=None)
- 选择你所需的编码和输出内容。
r.encoding = 'gbk'
r.encoding = 'UTF-8'
print(r.text)
print(r.text[:1000])
print(r.tontent)
print(r.json())
4. 实操练习-爬取京东商品页面信息
4.1. 确定请求方法和请求网址
【目标任务】
提取京东商品页面的相关信息,页面如下:
【确定请求方法】
这是网页分析的第一步,爬取其他网站也一样,大家照着操作即可。
- 在浏览器中输入要获取的商品页面网址,网址如下:
url = 'https://item.jd.com/10072335332864.html'
-
【F12】进入开发者工具。
-
点击网络【Network】。
-
点击【Fetch/XHR】。
-
【Ctrl+R】刷新页面。
-
点击名称【Name】栏。
-
任意点击一个下方的接口。
-
点击-【Headers】-【general】。
-
确定请求方法为【get】。
【确定请求网址】
请求方法为get
时,请求网址就是输入浏览器里的网址。
【请求网址】
url = 'https://item.jd.com/10072335332864.html'
4.2 代码
【代码示例】
import requests
url = 'https://item.jd.com/10072335332864.html'
r = requests.get(url)
print(r.status_code)
r.encoding = 'UTF-8'
print(r.text[:500])
【终端输出】
200
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8" version='1'/>
<title>京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes"/>
<meta name="description"
content="京东JD.COM-专业的综合网上购物商城,为您提供正品低价的购物选择、优质便捷的服务体验。商品来自全球数十万品牌商家,囊括家电、手机、电脑、服装、居家、母婴、美妆、个护、食品、生鲜等丰富品类,满足各种购物需求。"/>
<meta name="Keywords" content="网上购物,网上商城,家电,手机,电脑,服装,居家,母婴,美妆,个护,食品,生鲜,京东"/>
<script type="text/java
上面的代码是我们之前学过的,为了代码的稳定性我对代码进行了优化。
【优化代码】
import requests
url = 'https://item.jd.com/10072335332864.html'
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
print(r.text[:500])
except:
print("爬取失败!")
【终端输出】
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8" version='1'/>
<title>京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes"/>
<meta name="description"
content="京东JD.COM-专业的综合网上购物商城,为您提供正品低价的购物选择、优质便捷的服务体验。商品来自全球数十万品牌商家,囊括家电、手机、电脑、服装、居家、母婴、美妆、个护、食品、生鲜等丰富品类,满足各种购物需求。"/>
<meta name="Keywords" content="网上购物,网上商城,家电,手机,电脑,服装,居家,母婴,美妆,个护,食品,生鲜,京东"/>
<script type="text/java
输出的效果是一样的,代码解析放在后面的章节进行讲解。