爬虫笔记
一、爬虫使用场景分类
1.通用爬虫:
抓取系统重要组成部分。抓取的是一整张页面数据。
2.聚焦爬虫:
是建立再通用爬虫的基础上。抓取的是页面中特定的局部内容。
3.增量式爬虫:
检测网站中数据更新的情况。只会抓取网站中最新更新出来的数据。
了解概念:
反爬 门户网站,可以通过制定相应的策略或者技术手段,防止爬虫程序进行网站数据的爬取。
反反爬策略:
爬虫程序可以通过指定相关的策略或者技术手段,破解门户网站中具备的反爬机制,从而可以获取门户网站中相关的数据。
robots.txt协议:
网站规定的协议,规定网站中哪些信息可以被爬虫爬取。
二、常用协议
HTTP协议:
概念:就是服务器和客户端进行数据交互的一种形式。
常用请求头信息:
~User-Agent:请求载体的身份标识。
~Connection:请求完毕后,是断开连接还是保持连接。
常用响应头信息:
~Content-Type:服务器响应回客户端的数据类型。
HTTPS协议:
~安全的超文本传输协议,进行了数据加密。
加密方式:
~对称秘钥加密
~非对称秘钥加密
~证书秘钥加密
三、requests模块
注:urllib模块比较繁琐,基本用法都被urllib模块代替。
概念:基于网络请求的模块,功能强大,简单便捷,效率极高。
作用:模拟浏览器发请求。
环境安装:pip install requests
操作流程(requests模块编码流程)
1.指定url
2.发起请求
3.获取响应数据
4.持久化存储
import requests
if __name__== "__main__":
#1.指定URL
url = "https://www.sogou.com/";
#2.发起请求并且将响应数据保存到respense中
response = requests.get(url= url);
#3将respense中的数据以文本形式保存
page_text = response.text;
print(page_text);
#4.持久化存储,将爬取内容存储为网页
with open("./sogou.html" , 'w' , encoding='utf-8') as fp:
fp.write(page_text);
print("运行结束!");
实战项目
爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
UA(User-Agent)检测:门户网站的服务器会检测对应请求的载体身份标识,如果检测到请求的载体身份标识为某一款浏览器说明请求是一个正常的请求;但是,如果检测到请求的载体身份标识不是基于某一款浏览器的,则标识该请求为不正常的请求(爬虫),则服务器端就很有可能会拒绝请求。
UA(User-Agent)伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器。
import requests
if __name__== "__main__":
#UA伪装:将对应的User-Agent封装到一个字典中
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
url = 'https://www.sogou.com/web'
#处理URL携带的参数:封装到字典中
kw = input('enter a word:')
param = {
'qurey' : kw
}
#对指定的URL发起的请求对应的URL是携带参数的,并且请求过程中处理了参数
response = requests.get(url= url,params= param ,headers= headers)
page_text = response.text
fileName = kw+'.html'
with open (fileName,'w',encoding='utf-8') as fp:
fp.write(page_text)
print(fileName,'保存成功')
破解百度翻译
~post请求(携带了参数)
~响应数据是一组JSON数据,其页面数据再其network下XHR(为AJAX)内容中寻找其完整属性值。其中,只要页面发生局部刷新,就是发生了AJAX请求,就需要到XHR中去寻找数据。
import json
import requests
if __name__ == "__main__":
#1.指定URL
post_url = 'https://fanyi.baidu.com/langdetect'
#2.进行UA伪装
header ={
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
#3.post请求参数处理(同get请求一致)
word = input('enter a word:')
data = {
'kw' : word
}
#4.请求发送
response = requests.post(url = post_url,data= data,headers=header)
#5.获取响应数据:json()方法返回的是obj(如果确认响应数据是json类型的,才可以使用json() )
dic_obj = response.json()
#持久化存储
fileName = word+'.json'
fp = open(fileName , 'w' ,encoding='utf-8')
json.dump(dic_obj , fp=fp,ensure_ascii=False,sort_keys=True)
print('over!')
爬取豆瓣电影分类排行榜
正则表达式批量添加引号(json数据)
(.?)😦.) 查找 ‘$1’:‘$2’,(替换)
import requests
import json
if __name__ == "__main__":
get_URL = 'https://movie.douban.com/j/chart/top_list'
#UA伪装:将对应的User-Agent封装到一个字典中
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
#param这个参数来自query String parameters控制检索数据的范围参数
param ={
' type':' 24',
' interval_id':' 100:90',
'action':'',
' start':' 5',
' limit':' 5',
}
response = requests.get(url=get_URL,params=param,headers=headers)
page_json=response.json()
fp = open('./humonsrank.json','w',encoding='utf-8')
json.dump(page_json , fp=fp,ensure_ascii=False,sort_keys=True)
print('over!')
爬取肯德基餐厅查询中指定地点的餐厅数据
网址:http://www.kfc.com.cn/kfccda/index.aspx
import requests
#在代码下方添加 if __name__ == '__main__':
#的主要原因是有时你需要你写的模块既可以直接的执行,
# 还可以被当做模块导入到其他模块中去.通过检查是不是主函数,
# 可以让你的代码只在它作为主程序运行时执行,
# 而当其他人调用你的模块中的函数的时候不必执行。
# 简单来说就是,方便我们代码复用,也可以测试模块。
if __name__ == '__main__':
post_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
kw = input("输入:")
data = {
' cname':' ',
'pid':' ',
'keyword': kw,
'pageIndex':' 0',
'pageSize':' 10',
}
#UA伪装:将对应的User-Agent封装到一个字典中
headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
response = requests.post(url=post_url,data=data,headers=headers)
page_text = response.text
print(page_text)
fileName = kw+'.html'
with open (fileName,'w',encoding='utf-8') as fp:
fp.write(page_text)
print(fileName,'保存成功')
爬取国家药品监督管理总局中基于中华共和国化妆品生产许可证相关数据
——动态加载数据
——首页中对应的企业信息数据是通过AJAX动态请求到的
——通过对详情页URL的观察发现:
--URL的域名都是一样的,只有携带的参数(ID)不一样
--ID值可以从首页对应的AJAX请求到的JSON串中获取
--域名和ID值拼接出一个完整的企业对应的详情页的URL
——详情页的数据也是通过AJAX请求得到的
--观察后发现:
--所有的post请求的URL都是一样的,只有参数ID值是不同。
--如果我们可以批量的获取多家企业的ID后,就可以将ID和URL形成一个完整的详情页对应详细数据的AJAX请求的URL
import json
import requests
if __name__ == "__main__":
URL = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
ID_list = [] #存储企业的ID
all_data_list =[] #存储所有的企业详情数据
#page控制获取页面数据数量
for page in range(1,6):
page = str(page)
data = {
' on':'true',
' page': page,
' pageSize':'15',
' productName':'',
' conditionType':'1',
' applyname':'',
' applysn':'',
}
#获取首页面AJAX信息中附带的ID信息
ID_Json = requests.post(url=URL,data=data,headers=headers).json()
#将获取的ID信息存放到ID_list中
for dic in ID_Json['list']:
ID_list.append(dic['ID'])
post_URL = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
#通过ID_list的ID来获取相应的详细数据
for id in ID_list:
data1 = {
'id' : id
}
detail_json= requests.post(url=post_URL,data=data1,headers=headers).json()
# print(detail_json,'----------------------ending-----------------------')
#添加到all_data_list中临时存储
all_data_list.append(detail_json)
#持久化存储
fp = open('./allData.json','w',encoding='utf-8')
json.dump(all_data_list,fp=fp,ensure_ascii=False)
print('over!')
四、数据解析
目的:实现聚焦爬虫。
聚焦爬虫的实现步骤:
指定URL、发起请求、获取响应数、数据解析、持久化存储。
分类:
-正则表达式
-bs4
-xpath(重点)
原理概述:
-解析的局部文本内容都会在标签之间或者标签对应的属性中进行存储
-①进行指定标签的定位
-②标签或者标签对应的属性中存储的数据值进行提取(解析)
1.正则表达式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pf9jeCFi-1654417233092)(C:\Users\wait\AppData\Roaming\Typora\typora-user-images\image-20220116115213180.png)]
爬取图片信息
爬取单独的图片
import requests
url = 'https://i0.hippopx.com/photos/242/966/413/dawn-sun-mountain-landscape-preview.jpg'
header ={
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
#content返回的是二进制形式的图片数据
#text(字符串) content(二进制) jSON() (响应数据,对象)
picture = requests.get(url=url,headers=header).content
with open('./sence.jpg','wb') as fp:
fp.write(picture)
对所有的图片进行聚焦爬虫
import requests
import re
import os
#<img itemprop="contentUrl" alt="ipad, 样机, 苹果, 业务, 计算机, 平板电脑, 工作场所"
# title="ipad, 样机, 苹果, 业务, 计算机, 平板电脑,
# 工作场所" src="https://i0.hippopx.com/photos/1014/122/418/ipad-mockup-apple-business-preview.jpg">
#创建一个文件夹保存所有的图片
if not os.path.exists('./photo'):
os.mkdir('./photo')
url = 'https://www.hippopx.com/zh/query?q=ipad'
header ={
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
#使用通用爬虫对URL对应的一整张页面进行爬取
page_text = requests.get(url=url,headers=header).text
#print(page_text)
#使用聚焦爬虫对页面中所有的图片信息进行截取
ex = '<img itemprop="contentUrl" alt=(.*?) title=(.*?) src=(.*?)>'
img_src_list= re.findall(ex,page_text,re.S)
ex2 = 'https?://(.*?)"'
img_src_list2=re.findall(ex2,str(img_src_list))
for src in img_src_list2:
#拼接出一个完整的图片URL
src = 'https://' +src
#请求到了图片的二进制数据
img_data = requests.get(url=src,headers=header).content
#生成图片名称
img_name = src.split('/')[-1]
#图片存储路径
imgpath = './photo' +img_name
with open (imgpath,'wb')as fp:
fp.write(img_data)
print(img_name,'下载成功!')
对所有图片分页爬取
import requests
import re
import os
#创建一个文件夹保存所有的图片
if not os.path.exists('./photo'):
os.mkdir('./photo')
header ={
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
url = 'https://www.hippopx.com/zh/query?q=ipad&page=%d'
for pageNum in range(1,10):
#对应平均页码的url
new_url = format(url%pageNum)
#使用通用爬虫对URL对应的一整张页面进行爬取
page_text = requests.get(url=url,headers=header).text
#print(page_text)
#使用聚焦爬虫对页面中所有的图片信息进行截取
ex = '<img itemprop="contentUrl" alt=(.*?) title=(.*?) src=(.*?)>'
img_src_list= re.findall(ex,page_text,re.S)
ex2 = 'https?://(.*?)"'
img_src_list2=re.findall(ex2,str(img_src_list))
for src in img_src_list2:
#拼接出一个完整的图片URL
src = 'https://' +src
#请求到了图片的二进制数据
img_data = requests.get(url=src,headers=header).content
#生成图片名称
img_name = src.split('/')[-1]
#图片存储路径
imgpath = './photo/' +img_name
with open (imgpath,'wb')as fp:
fp.write(img_data)
print(img_name,'下载成功!')
2.bs4进行数据解析
bs4数据解析原理:
-1.实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
-2.通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取。
环境安装:
-pip install bs4
-pip install lxml
-如何实例化Beautifulsoup对象:
-from bs4 import beautifulsoup
-对象实例化:
-1.将本地的html文档中的数据加载到该对象中。
fp = open('./test.html','r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml')
-2.将互联网上获取的页面源码加载到该对象中。
page_text = response.text
soup = BeautifulSoup(page_text,'lxml')
-提供的用于数据解析的方法和属性:
– soup.tagName: 返回的是文档中第一次出现的tagName对应的标签
– soup.find():
--find(‘tagName’):等同于soup.tagName
– 属性定位:
--soup.find(‘div’,class_/id/attr=‘song’)
– soup.find_all(‘tagName’):返回符合要求的所有标签(列表)
– select:
--select(‘某种选择器(id, class,标签……选择器)’)返回的是一个列表。
– 层级选择器:
--soup.select(‘.tang > ul > li > a’): >表示的是一个层级
– soup.select(‘.tang > ul a’):空格标识多个层级
--获取标签之间的文本数据:
--soup.a.text/string/get_text()
--text/get_text():可以获取某一个标签中所有文本内容
--string:只可以获取该标签下面直系文本内容
– 获取标签中属性值:
– soup.a[‘tagName’]
爬取小说网站中小说的全部章节
import requests
from bs4 import BeautifulSoup
import lxml
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
#在首页中解析出章节的标题和详情页的url
#1.实例化BeautifulSoup对象,需要将页面源码数据加载到该对象中
page_enco = requests.get(url=url,headers=headers)
#解决编码错误问题
page_enco.encoding = 'utf-8'
page_text = page_enco.text
soup = BeautifulSoup(page_text,'lxml')
#解析章节标题和详情页url
title_text = soup.select('.book-mulu > ul > li')
#print(title_text)
fp=open('./sanguo.txt','w',encoding='UTF-8')
for li in title_text:
title = li.a.string
detail_url = 'https://www.shicimingju.com/'+li.a['href']
#对详情页发起请求,解析出章节内容
detail_name_enco = requests.get(url=detail_url , headers=headers)
detail_name_enco.encoding = 'utf-8'
detail_name_text =detail_name_enco.text
#解析出详情页中相关的章节内容
detail_soup = BeautifulSoup(detail_name_text,'lxml')
div_tag = detail_soup.find('div',class_='chapter_content')
#解析到了章节的内容
content = div_tag.text
fp.write(title+':'+content+'\n')
print(title,'爬取成功!')
3.xpath解析
最常用且最便捷高效的一种解析方式。通用性最强。
Xpath解析原理:
--1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。
--2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。
环境安装:
pip install lxml
如何实例化一个etree对象:
--1.将本地的html文档中的源码数据加载到etree对象中:
etree.parse(filePath)
– 2.可以将从互联网上获取的源码数据加载到该对象中
etree.HTML('page_text')
--xpath(‘xpath表达式’)
--. /表示从根节点开始定位。表示的是一个层级
--. //标识的是多个层级。可以表示从任意位置定位
tree = etree.parse('test.html')
r = tree.xpath('/html/body/div')
r = tree.xpath('/html//div')
r = tree.xpath('//div')
#三种结果一样
--. 属性定位://div[@class=‘song’] tag[@attrName=“attrValue”]
--.索引定位://div[@class=“song”]/p[3] 注:此时索引是从1开始的。
--.取文本:
--./test() 获取的标签中直系的文本内容
--.//test() 获取的标签中非直系的文本内容(所有的文本内容)
--.取属性:
--./@attrName ==>img/@src
#定位
r = tree.xpath('//div[@class="tagName"]')
#获取文本
r = tree.xpath('//div[@class="tagName"]//li[5]/a/test()')[0]
r = tree.xpath('//div[@class="tagName"]//test()')
#取属性
r = tree.xpath('div[@class="tagName"]/img/@src')
58同城二手房房源信息爬取
import requests
from lxml import etree
if __name__ =="__main__":
headers = {
'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
url = 'https://hn.58.com/ershoufang/'
page_text = requests.get(url=url,headers=headers).text
#数据解析
tree = etree.HTML(page_text)
#确定存储对象位置
list =tree.xpath('//div[@class="property-content-title"]/h3/text()')
fp = open('./58.txt','w',encoding='utf-8')
#遍历写入文件
for li in list:
print(li+'\n')
fp.write(li+'\n')
图片解析爬取(解决中文乱码问题)
import requests
from lxml import etree
url = 'https://pic.netbian.com/'
headers = {
'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
response = requests.get(url=url,headers=headers)
#手动设定响应数据的编码格式
#这种方式不行用下面的通用处理中文乱码的方式
#response.encoding = 'utf-8'
page_text = response.text
#解析数据
tree = etree.HTML(page_text)
li_list = tree.xpath('//div[@class="slist"]/ul/li')
for li in li_list:
img_src='https://pic.netbian.com/'+li.xpath('./a/span/img/@src')[0]
#print(img_src)
img_name = li.xpath('./a/@title')[0]
#print(img_name)
img_data = requests.get(url=img_src,headers=headers).content
img_path = './photo/' + img_name +'.jpg'
#通用处理中文乱码的解决方案
img_name = img_name.encode('iso-8859-1').decode('gbk')
#持久化存储
with open(img_path,'wb')as fp :
fp.write(img_data)
print(img_name,'download successful!')
爬取网页中全国城市的名称
#分开取数据写法
import requests
from lxml import etree
if __name__ == '__main__':
url = 'https://www.aqistudy.cn/historydata/'
headers = {
'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
page_text = requests.get(url=url,headers=headers).text
tree = etree.HTML(page_text)
hot_li_city = tree.xpath('//div[@class="bottom"]/ul/li')
city_name = []
#解析到了热门城市的城市名称
for hot_city in hot_li_city:
city = hot_city.xpath('./a/text()')[0]
city_name.append(city)
#解析的是全部城市的名称
city_name_list = tree.xpath('//div[@class="bottom"]/ul/div/li')
for city_n in city_name_list:
city_na = city_n.xpath('./a/text()')[0]
city_name.append(city_na)
print(city_name,len(city_name))
#合并取数据写法(使用逻辑表达式)
import requests
from lxml import etree
if __name__ == '__main__':
url = 'https://www.aqistudy.cn/historydata/'
headers = {
'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
page_text = requests.get(url=url,headers=headers).text
tree = etree.HTML(page_text)
#解析到热门城市和所有城市对应的a标签
#div/ul/li/a ('//div[@class="bottom"]/ul/li') 热门城市a标签的层级关系
#div/ul/div[2]/li/a ('//div[@class="bottom"]/ul/div/li') 全部城市a标签的层级关系
#xpath表达式可以使用逻辑表达式!
a_list = tree.xpath('//div[@class="bottom"]/ul/li | //div[@class="bottom"]/ul/div/li')
all_city_list = []
for li in a_list:
city_name = li.xpath('./a/text()')[0]
all_city_list.append(city_name)
print(all_city_list,len(all_city_list))
爬取站长素材中免费简历模板
五、验证码识别
门户网站提供的一种反爬机制:叫做验证码。
识别验证码图片中的数据,用于模拟登录操作。
识别验证码的操作:
– 人工肉眼识别。(不推荐)
– 第三方自动识别。(推荐)
– 云打码平台(收费价格不贵):http://www.yundama.com/demo.html(倒闭了)
--其他平台,测试可以使用后补充
1.模拟登录
--爬取基于某些用户的用户信息。
需求:对人人网进行模拟登录。
– 点击登录按钮之后会发起一个post请求
– post请求中会携带登录之前录入的相关登录信息(用户名,密码,验证码……)
– 验证码:每次请求都会变化
编码流程:
-1.验证码识别,获取验证码图片的文字数据
-2.对post请求进行发送(处理请求参数)
-3.对响应数据进行持久化存储
import requests
from lxml import etree
#这里需要导入打码平台示例代码中所需要的类
#导入打码平台示例代码并且将其封装成函数
url = 'https://www.renren.com/SysHome.do'
headers = {
'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
#1.验证码识别,获取验证码图片的文字数据
page_text = requests.get(url=url,headers=headers).text
tree = etree.HTML(page_text)
code_img_src = tree.xpath('//*[@id="verifyPic_login"]/@src')[0]
code_img_data = requests.get(url=code_img_src,headers=headers).content
with open('./code.jpg','wb') as fp:
fp.write(code_img_data)
#使用打码平台提供的示例代码对验证码图片进行识别(调用函数)
#对post请求的发送
#login_url
#data值的修改
#验证是否登录成功,打印response.status_code状态码,为200即为成功
cookie操作
–http/https协议特性:无状态。
没有请求到对应页面数据的原因:
发起的第二次基于个人主页页面请求的时候,服务端并不知道该请求是基于登录状态下的请求。
–cookie:用来让服务器端记录客户端的相关状态。
--手动处理:通过抓包工具获取cookie值,将该值封装到headers中(不建议)
--自动处理:
--cookie值的来源是哪里?
--模拟登录post请求后,由服务器端创建。
session会话对象:
--作用:
1.可以进行请求的发送。
2.如果请求过程中产生了cookie,则该cookie会被自动存储/携带在该session对象中。
--创建一个session对象:session = requests.Session()
--使用session对象进行模拟登陆post请求的发送(cookie就会被存储在session中)
--session对象对个人主页对应的get请求进行发送(携带了cookie)
2.代理
代理:破解封IP这种反爬机制。
什么是代理:
--代理服务器。
代理的作用:
--突破自身IP访问的限制。
--隐藏自身真实的IP。
代理相关网站:
--快代理
--西祠代理
--www.goubanjia.com
40异步爬虫(目前暂时用不到)
.write(code_img_data)
#使用打码平台提供的示例代码对验证码图片进行识别(调用函数)
#对post请求的发送
#login_url
#data值的修改
#验证是否登录成功,打印response.status_code状态码,为200即为成功
#### cookie操作
--http/https协议特性:无状态。
没有请求到对应页面数据的原因:
发起的第二次基于个人主页页面请求的时候,服务端并不知道该请求是基于登录状态下的请求。
--cookie:用来让服务器端记录客户端的相关状态。
--手动处理:通过抓包工具获取cookie值,将该值封装到headers中(不建议)
--自动处理:
--cookie值的来源是哪里?
--模拟登录post请求后,由服务器端创建。
session会话对象:
--作用:
1.可以进行请求的发送。
2.如果请求过程中产生了cookie,则该cookie会被自动存储/携带在该session对象中。
--创建一个session对象:`session = requests.Session()`
--使用session对象进行模拟登陆post请求的发送(cookie就会被存储在session中)
--session对象对个人主页对应的get请求进行发送(携带了cookie)
### 2.代理
代理:破解封IP这种反爬机制。
什么是代理:
--代理服务器。
代理的作用:
--突破自身IP访问的限制。
--隐藏自身真实的IP。
代理相关网站:
--快代理
--西祠代理
--www.goubanjia.com
40异步爬虫