1,requests的get请求的发送

 

  • 什么是requests模块:requests模块是Python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能强大,用简洁高效的语言,在爬虫领域占据着半壁*的位置
  • requests向比较与urllib的request的极大优势:
    • 不用手动处理url编码
    • 不用手动处理post请求参数
    • 不用处理cookie和繁琐的代理操作
  • requests模块的使用
    1. 安装:pip install requets
  • 使用requests
    1. 指定要请求的url
    2. 基于requests模块发起请求
    3. 获取响应对象中的数据值
    4. 持久化存储

2,具体相关代码:

import requests
import os
# 指定搜索关键字
word = input("enter a word you want to search:")
# 自定义请求头信息
headers = {
    "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
# 指定url
url = "https://www.sogou.com/web"
# 封装get请求参数
params = {
    "query": word,
    "ie": "utf-8"
}
# 向网址发请求
response = requests.get(url=url, params=params)
print(response)
# <Response [200]>
# 获取响应数据
page_text = response.text

# 持久化存储
with open("./sougou.html", "w", encoding="utf-8") as fp:
    fp.write(page_text)
  • 请求载体的身份表示的伪装:
    • User-Agent:请求载体身份标识,通过浏览器发起的请求,请求载体为浏览器,则该请求的User-Agent为浏览器的身份标识,使用爬虫程序发起的请求,则该请求的载体为爬虫程序,则该请求的User-Agent为爬虫程序的身份标识,可以通过判断值来获取该请求的载体究竟是基于 浏览器还是基于爬虫程序来的
    • 反爬机制:某些门户网会对访问该网站的请求中User-Agent进行捕获和判断,如果该请求的UA为爬虫程序,则拒绝向该请求提供该数据
    • 反反爬策略:将爬虫程序的UA伪装成某一款浏览器的身份标识

爬取豆瓣电影,爬取登录成功后的页面数据

 

# 2豆瓣电影的数据的抓取(ajax的get请求的发送)
import requests
import os
# 发情求的url
url = "https://movie.douban.com/typerank"
# 制定请求头的信息,相关的头信息必须封装在字典结构中
headers = {
    "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
# 定制get请求携带的参数
param = {
    "type": "13",
    "interval_id": "100:90",
    "actions": "",
    "limit": "20",
}
# 发get请求, 获取响应对象
response = requests.get(url=url, headers=headers, params=param)
print(response.text)

 requests模块的post请求

import requests
import os
url = "https://accounts.douban.com/j/mobile/login/basic"
# 封装请求的参数
data = {
    "ck":"",
    "name": "18731229751",
    "password": "jiji0923",
    "remember": "false",
    "ticket":""
}
# 自定义请求头信息
headers = {
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}

response = requests.post(url=url, data=data)
print(response)
page_text = response.text

# 持久化存储
with open("./douban.html", "w", encoding="utf-8") as fp:
    fp.write(page_text)

requests模块的ajax请求

import requests
if __name__ == '__main__':
    print(123)
    # 指定ajax-post请求的url(通过浏览器获取)
    url = "http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword"
    # 定制请求头信息,相关信息封装在字典结构中
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
    }
    print(456)
    # 定制post请求携带的参数(从浏览器装包中获取到network)
    data = {
        "cname": "",
        "pid": "",
        "keyword": "北京",
        "pageIndex": "1",
        "pageSize": "10",
    }
    # 发送post请求的信息,获取响应对象
    print("哈哈哈")
    response = requests.post(url=url, headers=headers, data=data)
    print(789)
    # 获取响应内容,响应内容为串
    print(response.text)
  • 获取食药监中华人名*关于化妆品生产许可的数据
import requests
from fake_useragent import UserAgent

ua = UserAgent(use_cache_server=False, verify_ssl=False)
headers = {
    "User-Agent": ua
}
url = "http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList"
# 定义一个全局的变量
pageNum = 3
for page in range(3,5):
    data = {
        "on": "true",
        "page": str(page),
        "pageSize": "15",
        "productName": "",
        "conditionType": "2",
        "applyname":"",
        "applysn":""
    }
    # 发送请求
    json_text = requests.post(url=url, data=data, headers=headers).json()
    all_id_list = []
    # 循环这个响应字典的列表,拿到每一个信息
    for dict in json_text["list"]:
        id = dict["ID"]
        all_id_list.append(id)
    # 发送post请求获取详情数据
    post_url = "http://125.35.6.84:81/xk/itownet/portal/dzpz.jsp"
    for id in all_id_list:
        post_data = {
            "id": id
        }
        response = requests.post(url=post_url, data=post_data, headers=headers)
        if response.headers["Content-Type"] == "application/json;charset=UTF-8":
            json_text = response.json()
            print(json_text["businessPerson"])

小结:在爬取数据的时候,如果是是get请求获取到的是html页面,一般获取到的响应对象的text即可,如果是post请求,服务器返回的响应json格式的数据(尤其是ajax请求,返回的数据),数据采集的步骤如下:

  1. 获取目标数据页面的url
  2. 定制User-Agent请求头,浏览器的伪装
  3. 如果是get请求就直接用requests发送get请求,拿到响应体.text
  4. 如果是post请求就需要定制post的请求携带参数data
  5. 如果有二级页面的数据,需要再根据二次页面的url,在指定请求的参数发送请求,详情见KFC和国家药监总局

3,requests的session处理cookie

  • 在有些时候我们在爬取一些用户相关信息的时候,如果使用之前的requests模块常规操作,往往会达不到想要的效果
  • 在requests中的cookie的操作:
  • cookie概念:当用户通过浏览器收悉访问一个域名时,访问web服务器会给客户端发送数据,以保持web服务器与客户端之间状态保持,这些就是cookie
  • cookie的作用:我们在浏览器中,经常涉及到数据的交换,比如登录邮箱,登录一个页面的时候,我们经常会在此设置30天记住我,或者自动登录状态,他们是怎么记录信息的呢?Cookie是有HTTP服务器设置的,保存在浏览器中,但HTTP协议是一种无状态协议,在数据交换完毕后,服务器和客户端,浏览器和服务器的连接就会关闭,每次交换数据都是需要建立新的连接,就想我们去超市买东西,没有积分卡的时候,我们买完东西后超市没哟无偶们任何的消费信息,但是我们办了积分卡后,可以保存积分,商品就是我们的信息,超市的系统就想我们服务器的后台,http协议就是交易的过程
  • 思路:
    • 我们需要使用爬虫程序对人人网的登录是的请求进行一次抓取,获取请求中的cookie
    • 在使用个人信息页的url进行请求时,该请求要携带撒花姑娘变的cookie,服务器才可再次识别再次请求的用户信息,方可响应指定用户页面的信息

 

import requests
if __name__ == '__main__':
    # 登录请求的url
    post_url = "http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2019062051812"
    # 创建一个session对象,该对象会自动将请求中的cookie进行存储和携带
    session = requests.session()  # requests中有一个session对象
    # 伪装UA
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
    }

    # post请求要提交的数据
    formdata = {
        "email": "18731229751",
        "icode": "",
        "origURL": "http://www.renren.com/home",
        "domain": "renren.com",
        "key_id": "1",
        "captcha_type": "web_login",
        "password": "054c50afb1d1c5f6bc9e45954178a019f0e3b01ea098c68964201846148cdb78",
        "rkey": "39b392090c635431e86ef76d46f31f40",
        "f": "http%3A%2F%2Fwww.renren.com%2F969397800",
    }

    # 使用session发送请求,目的是为了将session保存该次请求中的cookie
    session.post(url=post_url, data=formdata, headers=headers)
    get_url = "http://www.renren.com/969397800"
    # 如果在此发送请求的时候,这时session中已经携带了cookie
    response = session.get(url=get_url, headers=headers)
    # 设置响应格式内容的编码
    response.encoding = "utf-8"
    #将响应的内容写入到文件中
    with open("./renren.html","w") as fp:
        fp.write(response.text)

 

4基于requests的代理操作

  • 什么是代理:代理就是代替第三方本体处理年相关事务
  • 爬虫中为什们需要使用代理:
    • 一些网站会有相应的反爬虫措施,列如很多网站会检测某一段时间某个人IP的访问时间,如果访问频率太快以至于太快看起来不像正常的访客,它可能就会禁止这个IP的访问,所有我们需要一些代理IP,每个一段时间换一个IP,就算IP被禁止,依然可以换个IP继续爬取
  • 代理的分类:
    • 正向代理:代理客户端获取数据,正向代理是为了保护客户端防止被追究责任
    • 反向代理:代理服务器提供该数据,反向代理是为了保护服务器或负责负载均衡
  • 免费代理IP:百度很多,一搜便是

 单线程的数据抓取:

#  梨视频数据的爬取
import requests
import random
from lxml import etree
import re
from fake_useragent import UserAgent
# 安装fake_useragent: pip install fake_useragent
url = "https://www.pearvideo.com/category_8"
ua = UserAgent().random
# 定制请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
}
# 获取首页页面数据
page_text = requests.get(url=url, headers=headers).text
# print("111", page_text)
# 获取首页页面数据的相关视频详情连接进行解析
tree = etree.HTML(page_text)
li_list = tree.xpath("//div[@id='listvideoList']/ul/li")
print("哈哈哈", li_list)
# 详情的url
detail_urls = []  # type:list
for li in li_list:
    detail_url = "http://www.pearvideo.com/" + li.xpath("./div/a/@href")[0]  # 此时返回的是一个列表
    print("222",detail_url)
    title = li.xpath("./div/a/div[@class='vervideo-title']/text()")[0]
    detail_urls.append(detail_url)

print(detail_urls)
# 拿到每一个详情url发送get请求
for url in detail_urls:
    page_text = requests.get(url=url, headers=headers).text
    video_url = re.findall('srcUrl="(.*?)"', page_text, re.S)[0]
    print("啧啧啧", video_url)

    # 向视频的详情发送请求
    data = requests.get(url=video_url, headers=headers).content
    fileName = str(random.randint(1,10000)) + '.mp4'  # 随机生成视频文件

    # 存储得到本地
    with open(fileName, "wb") as fp:
        fp.write(data)
        print(fileName + "下载成功!")

线程池的数的爬取:

import requests
from lxml import etree
import re
import random
# 开一个线程池
from multiprocessing.dummy import Pool
pool = Pool(5)
def saveVideo(data):
    name = str(random.randint(0,10000)) + ".mp4"
    with open(name, "wb") as fp:
        fp.write(data)
        print(name + "下载成功!")
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
}
# 拿到梨视频的url
url = "https://www.pearvideo.com/category_8"

page_text = requests.get(url=url, headers=headers).text
tree = etree.HTML(page_text)
# 拿到的是每一个视频对应的url
li_list=tree.xpath("//div[@id='listvideoList']/ul/li/div/a/@href")  # '//ul[@class="listvideo-list clearfix"]/li/div/a/@href'
print(li_list)

# 准备一个列表去存放视频的url
video_url_list = []

# 拼接视频的详细url
for li in li_list:
    detail_page_url = "https://www.pearvideo.com/" + li
    # 发请求
    detail_page_text = requests.get(url=detail_page_url, headers=headers).text
    # 这样呀,还没拿到视频的url只拿到一个关于url的i标签和img标签
    video_url = re.findall('srcUrl="(.*?)"', detail_page_text, re.S)[0]
    print(video_url)
    video_url_list.append(video_url)

# 并发瞎下载视频
downloadVideo = lambda link: requests.get(url=link, headers=headers).content
# map 返回的是列表中存储的下载完毕的二进制的视频
video_data_list = pool.map(downloadVideo, video_url_list)
# 把每一个二进制视频写进文件中
pool.map(saveVideo, video_data_list)
pool.close()
pool.join()

 

分类:

技术点:

相关文章: