爬虫:可见即可爬   # 每个网站都有爬虫协议

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

基础爬虫需要使用到的三个模块

requests 模块  # 模拟发请求的模块

PS:python原来有两个模块urllib和urllib的升级urllib2,这两个模块使用很繁琐,后来在这两个模块上做了封装就出现了requests模块

beautifulsoup 模块  #数据解析库,re模块正则匹配解析库

senium 模块  # 控制浏览器模块

scrapy 模块  # 把上面三个模块进行一个封装,做成一个大框架,可以做分布式爬虫

 

requests的基本使用  # 使用 pip3 install requests

requests.get请求

requests.get方法就是帮你凑出一个http请求发送

有三个参数

url : 就是访问的地址

headers: 请求头

params : 输入的内容和页码

 

响应response的参数

response.text   文本内容   # 文本内容取值

response.content  二进制内容  # 如果是图片和视频就要用这个方法取值

rsponse.iter_content()  # 如果一个视频或者图片文件非常大,如果一次性取值就会撑爆内存,所以要用这个iter_content,相当于for循环接收保存

response.status_code  状态码   #用来获取状态码

response.headers   响应头   # 以字典形式

response.cookies   返回的cookie

response.cookies.get_dict()   把取到的cookie转成字典形式

response.cookies.items()   和字典的items同理

response.url   拿出要重定向的地址

response.history  拿出正常返回的数据   # 和text相同

response.encoding   返回数据的编码格式 

response.apparent_encoding  # 获取当前页码的编码格式

PS:现在网站都有反扒技术,所以在模拟发送请求的时候尽量的要模拟的像浏览器一样,否则容易被反扒技术拦截,就算返回200状态码,也是网站返回的假状态码

 

Request Headers  # 这些是请求头的内容,这个直接从浏览器里面复制即可

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8  

Accept-Encoding:gzip, deflate, br

Accept-Language:zh-CN,zh;q=0.9

Cache-Control:max-age=0

Connection:keep-alive

Referer:https://www.lagou.com/    # 有些网站的请求头里面会有这一行用来判断是不是当前域,这个作用就是用来统计流量从哪一个网站跳转过来的,也可以实现反扒,就是所有的跳转地址都要在程序设定的地址跳转过来,图片防盗链也是用这个实现

'''正常的cookie写在请求头中,但是因为要经常用,所有requests模块把这个单独拿出来做了处理,请求头中最有用的一个参数就是user_session,当然也可以把整个cookie复制过来'''

Cookie:BAIDUID=8472CC0AF18E17091C3918C619E26E6D:FG=1; BIDUPSID=8472CC0AF18E17091C3918C619E26E6D; PSTM=1553224384; BD_UPN=1a314353; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; H_PS_645EC=d40c8VmPu6D48Clciaof7nl3ZoeWgKbduZIrfnNW%2FgKxKTRWYmN4scXUrJA; delPer=0; BD_HOME=0; H_PS_PSSID=1462_21120_28771_28721_28557_28833_28585_28640_26350_28604

Host:www.baidu.com  #  可以用来判断是不是当前的域,这个用的少

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6824.400 QQBrowser/10.3.3127.400  # 这个是浏览器类型,包含浏览器的信息,一般在发送请求的时候都要携带这个

PS:在爬虫的时候一直失败,肯定是模拟的不够像浏览器,所以用浏览器访问一次网站,查看下请求头的内容

 

request的基本使用和get请求实例

import requests  # 爬虫需要用到的模块,模拟发送请求

'''requests的基本使用'''

# 输入中文和特殊字符需要编码
# 如果 查询关键词是中文或者是其他特殊符号,则不的不进行url编码,否则会乱码 'https://www.baidu.com/s?wd=%E8%A5%BF%E7%93%9C'这里地址内的乱码符号就是被转码后的中文或者特殊字符
# 可以from urllib.parse import urlencode #使用这个模块对输入的中文或特殊字符进行编码,但是requests自带了一个参数,param可以实现编码并且自动拼接到地址的后面


key = input('请输入需要的内容: ')
# 发送get请求有返回结果
url = 'https://www.baidu.com'

# 正常的cookie写在请求头中,但是因为要经常用,所有requests模块把这个单独拿出来做了处理
cookies = {'user_session':'BAIDUID=8472CC0AF18E17091C3918C619E26E6D:FG=1; BIDUPSI'}

# 反扒信息之一,要携带头信息的浏览器信息
res = requests.get(url,
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6824.400 QQBrowser/10.3.3127.400'},
# baidu的页码规律是0=1,10=2的一个10倍数的跳转,所以params里面也可以拼地址进去直接跳转到指定的页数,就是get形式携带的参数
params={'wd': key, 'pn': 70},
cookies=cookies
)

# 这里将获取到的页面内容写入文件,用来验证是否成功
with open('a.html', 'w', encoding='utf-8')as f:
f.write(res.text)

# 请求回来的内容,text是整个页面的内容
print(res.text)

# 请求回来的状态码
print(res.status_code)

 

request的基本使用和post请求实例

post请求参数  # 和get请求类似

param  # 输入的内容和页码

headers  # 请求头

Cookie  # cookie

data # 请求体的数据,默认用urlencode格式

json  # 传字典,这样发送的请求编码格式是 'content-type':'application/json'

allow_redirects=False  # 是否允许重定向,不写就是默认True,通常不会关闭后续操作可能会出问题

PS:先用错误的账号密码登陆,就可以在检查里看到请求发送的地址以及请求发送的数据格式  # 看图

 项目实操(爬虫) 随笔

import requests, re

# 第一步
res_login = requests.get('https://github.com/login') # 访问页面获得返回数据
authenticity_token = re.findall(r'name="authenticity_token".*?value="(.*?)"',res_login.text,re.S)[0] # .*?正则表达式贪婪匹配,()是分组匹配,取出来的是一个列表,取索引位0的数据,re.S把字符串看成一行忽略字符串中的换行符
login_cookie = res_login.cookies.get_dict() # 这里获取一个没有经过认证的cookie
# 第二步
data = {
'commit': 'Sign in',
'utf8': '✓',
'authenticity_token': authenticity_token,
'login': 'Dragon-Killing',
'password': 'Dk581588',
'webauthn-support': 'unsupported',
} # 这个就是网页里面Form Data携带的数据,就是请求体的数据

res = requests.post(url='https://github.com/session',
data=data,
# 这里也需要携带一个未认证的cookie,现在很多网站都在首次登陆时候都要求携带未认证的cookie,这也是一种反扒手段
cookies=login_cookie)

# 正常登陆成功,返回cookie,下次发送请求携带者cookie
res_cookie = res.cookies.get_dict() #res是一个对象,从对象中获取cookie,然后转成字典

# 第三步
url='https://github.com/settings/emails'
res = requests.get(url,
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6824.400 QQBrowser/10.3.3127.400'},
# baidu的页码规律是0=1,10=2的一个10倍数的跳转,所以params里面也可以拼地址进去直接跳转到指定的页数,就是get形式携带的参数
cookies=res_cookie
)

print('邮箱号' in res.text) # 这里判断邮箱是否在返回的数据中,成功就是True

 

requests模块中的session方法  # 返回一个对象,用这个方法发送get和post请求,只要网站返回的cookie,则发送请求的时候自动携带cookis,不用再手动获取然后再写入

import requests
import re

session = requests.session()

# 第一次发送请求
r1 = session.get('https://github.com/login')
authenticity_token = re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #从页面中拿到CSRT_TOKEN
print(authenticity_token)

#第二次请求
data = {
'commit': 'Sign in',
'utf8': '✓',
'authenticity_token': authenticity_token,
'login': 'Dragon-Killing',
'password': 'Dk581588',
}

r2=session.post('https://github.com/session',data=data)

#第三次请求
r3=session.get('https://github.com/settings/emails')

print('402821597@qq.com' in r3.text)

 

前端往后台发送数据,有三种方式

1、urlencode  #data发送数据就是默认这个格式

2、formdate  # 传文件的编码

3、json  # 如果后端要求发送的是json格式,就用这个格式

requests.post (url='http://xxx.com',data={'xxx':'yyy'})  # 如果没有指定请求头,则默认的请求头就是:application/x-www-form-urlencoed

#如果定义的请求头是application/json,并且用data传值,则服务端取不到值

requests.post(url='',data={'xxx':'xxx'},headers={'content-type':'appilcation/json'})  #这里用data传值,但是指定了json请求头,所以服务端取不到数据

request.post(url='',json={'xxx':1})  # 这里用json传值,但是没有指定请求头,则默认根据传值的类型匹配请求头,这里就是默认是application/json格式请求头

 

 

如果在爬去页面的时候发生乱码,则肯定是编码问题,通过下面实例的方式解决编码的问题

import requests

response = requests.get('http://www.autohome.com/news')
ret = response.apparent_encoding # 获取当前页码的编码格式
response.encoding=ret # 指定解码的格式
print(response.text)

 

对于图片和视频的爬取保存,必须是二进制形式保存,所以要用content获取二进制流保存

import requests

response = requests.get('https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2602558426,100251765&fm=26&gp=0.jpg')
with open('a.jpg','wb')as f:
f.write(response.content)

对于很大的视频文件,一次性取值则肯定很耗费内存,则用iter_content比较合适

import requests

# 这里发请求的时候一定要跟一个stream=True
response = requests.get('https://gs33.baidu.com/eer7rer7e878df7d8f7d8f.mp4',stream=True)

# 这样就迭代的一行一行取值,用来爬视频
with open('a.mp4','wb')as f:
for line in response.iter_content():
f.write(line)

解析json格式的数据

import requests,json
response = requests.get('http://httpbin.org/get') #加入这里返回的格式是json格式

# res = json.loads(response.text) 用内置的方法去转换则要异步
res = response.json() # resquests实例化对象后可以直接获取json数据,就是封装了json的方法,直接转成数据原有的格式

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄