爬虫基础-request模块使用

requests基本操作

  • requests作用:
    • 就是一个基于网络请求的模块,可以用来模拟浏览器发请求。
  • 环境安装:
    • pip install requests
  • requests模块的使用流程:
    • 指定一个字符串形式url
    • 发起请求
    • 获取响应数据
    • 持久化存储
#需求:爬取搜狗首页的页面源码数据
import requests
#1.指定url
url = 'https://www.sogou.com/ '
#2.发起请求
response = requests.get(url=url)#get返回一个响应对象
#3.获取响应数据
page_text = response.text #获取字符串形式的响应数据
print(page_text)
#4.持久化存储
with open('./sogou.html','w',encoding='utf-8') as fp:
    fp.write(page_text)
url = 'https://www.sogou.com/web?query=jay'
response = requests.get(url=url)
page_text = response.text
with open ('./jay.html','w',encoding='utf-8') as fp:
    fp.write(page_text)
  • 上述代码出现了问题

    • 出现了乱码问题
    • 数据量级不对
  • 当次的请求被搜狗认定为是一个异常的请求

    • 什么是异常的请求?
      • 服务器端检测到该次请求不是基于浏览器访问。使用爬虫程序发起的请求就是异常的请求
    • User-Agent:
      • 本身是请求头中的一个信息。
      • 概念:请求载体的身份标识
        • 请求载体:浏览器,爬虫程序
  • 反爬机制:UA检测

    • 对方服务器端会检测请求载体的身份标识,如果不是基于某一款浏览器的身份标识则认定为是一个异常请求,则不会响应返回正常的数据。
  • 反反爬策略:UA伪装

    • 将爬虫程序发起的异常的请求载体标识伪装或者修改成某一款浏览器的身份标识即可。
#解决乱码问题
url = 'https://www.sogou.com/web?query=jay'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
#UA伪装
response = requests.get(url=url,headers=headers)

# response.ecncoding#返回响应数据原始的编码格式
response.encodingcoding = 'utf-8'
page_text = response.text
with open ('./jay.html','w',encoding='utf-8') as fp:
    fp.write(page_text)

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36

  • 参数动态化
    • 可以动态的给请求指定请求参数
key = input('enter a key word:')
#将请求参数封装成键值对
params = {
    'query':key
}
url = 'https://www.sogou.com/web'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}
response = requests.get(url=url,headers=headers,params= params)
# response.ecncoding#返回响应数据原始的编码格式
response.encodingcoding = 'utf-8'
page_text = response.text
fileName = key+'.html'
with open (fileName,'w',encoding='utf-8') as fp:
    fp.write(page_text)
print(fileName,'爬取成功!!!')
  • 爬取动态加载的数据

    • 所谓动态加载的数据是指不是通过浏览器地址栏的url请求到的数据。
    • 如何检测我们爬取的数据是否为动态加载的数据?
      • 基于抓包工具做局部搜索(在抓包工具中找到地址栏url对应的数据包,在其response这个选项卡下进行搜索爬取数据的关键字)
    • 如何爬取动态加载的数据?
      • 基于抓包工具做全局搜索,可以帮我们定位到动态加载的数据到底是存在于哪一个数据包中,定位到之后,就可以对该数据包的url进行请求发送捕获数据。
  • 爬取豆瓣中更多电影详情数据

    • 当滚轮向下滑动的时候,会加载出更多的电影数据,说明当滚轮滑动到底部时,会发起一个ajax请求,该次请求会加载出更多的数据。
url = 'https://movie.douban.com/j/chart/top_list'
params = {
    'type': '5',
    'interval_id': '100:90',
    'action': '',
    'start': '0',
    'limit': '100',
}
headers = {
    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'
}
#json()返回字典或者列表对象
data_list = requests.get(url=url,headers=headers,params=params).json()
for dic in data_list:
    title = dic['title']
    score = dic['score']
    print(title,score)
  • 动态加载数据的生成方式:

    • ajax请求
    • js
  • 日后对一个陌生的网站进行数据爬取,在编码之前必须要做的一件事情是什么?

    • 检测你要爬取的数据是否为动态加载的数据
      • 如果不是动态加载数据就可以直接对地址栏的url发起请求爬取数据
      • 如果是动态加载数据就需要基于抓包工具进行全局搜索爬取数据
  • 需求:

url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
city = input('enter a city name:')
for page in range(5):
    data = {
        'cname': '',
        'pid': '',
        'keyword': city,
        'pageIndex': str(page),
        'pageSize': '10',
    }
    #参数动态化使用的是data参数
    data_dict = requests.post(url=url,headers=headers,data=data).json()
    print(data_dict)
  • 需求:
  • 分析:
    • 尝试着将某一家企业的详情数据爬取到,然后再把此操作作用到其他家企业爬取到所有企业的数据。
    • 检测某一家企业详情数据是否为动态加载的数据
      • 基于抓包工具实现局部搜索
        • 结论:为动态加载数据
    • 基于抓包工具进行全局搜索定位动态加载数据的数据包,从数据包中提取url和请求参数
url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById'
data = {
    'id':'d82345168acb46f8a8b1fad2c8b5adce'
}
detail_json = requests.post(url=url,headers=headers,data=data).json()
per_name = detail_json['businessPerson']
addr = detail_json['epsAddress']
print(per_name,addr)
#尝试着将所有企业的id获取,将其作用到post请求的参数中即可
#思考:id应该是和企业名称关联在一起的,只要找到企业名称就有可能找到企业id,发现企业名称是动态加载的
post_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList'
for page in range(6):
    data = {
        'on': 'true',
        'page': str(page),
        'pageSize': '15',
        'productName': '',
        'conditionType': '1',
        'applyname': '',
        'applysn':'',
    }
    json_data = requests.post(url=post_url,headers=headers,data=data).json()
    for dic in json_data['list']:
        company_id = dic['ID']
        print(company_id)
url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById'
data = {
    'id':'d82345168acb46f8a8b1fad2c8b5adce'
}
detail_json = requests.post(url=url,headers=headers,data=data).json()
per_name = detail_json['businessPerson']
addr = detail_json['epsAddress']
print(per_name,addr)
#完整代码
post_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList'
fp = open('company_data.txt','a+',encoding='utf-8')
for page in range(6):
    data = {
        'on': 'true',
        'page': str(page),
        'pageSize': '15',
        'productName': '',
        'conditionType': '1',
        'applyname': '',
        'applysn':'',
    }
    json_data = requests.post(url=post_url,headers=headers,data=data).json()
    for dic in json_data['list']:
        company_id = dic['ID']

        url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById'
        data = {
            'id':company_id
        }
        detail_json = requests.post(url=url,headers=headers,data=data).json()
        per_name = detail_json['businessPerson']
        addr = detail_json['epsAddress']
        print(per_name,addr)
        fp.write(per_name+':'+addr+'\n')
fp.close()
  • 图片数据的爬取
    • urllib
    • requests
      • urllib和requests的功能作用都几乎是一致。urllib是一个比较古老的网络请求模块,当requests问世后,就快速的替代了urllib。
#爬取图片方式1
url = 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=4250058738,780121024&fm=11&gp=0.jpg'
#content返回二进制类型的响应数据
img_data = requests.get(url=url,headers=headers).content
with open('123.png','wb') as fp:
    fp.write(img_data)
#爬取图片方式2
from urllib import request
url = 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=4250058738,780121024&fm=11&gp=0.jpg'
request.urlretrieve(url=url,filename='./456.png')

  • 上述两者图片爬取方式的区别:
    • 方式1是可以进行UA伪装
    • 方式2无法进行UA伪装
posted @ 2023-01-31 13:03  一头钻进被窝里  阅读(42)  评论(0编辑  收藏  举报