网络爬虫06.18

昨日内容回顾

  • requests模块发送post请求

    requests.post(url,data={})
    
  • 代码模拟登录(重要)

    """
    编写爬虫的基本思路
    	先用浏览器正常操作
    	之后查找相应的目标数据及规律
    	最后使用代码爬取
    """
    1.查找数据提交的地址
    2.查找请求体数据格式
    3.代码模拟发送数据
    4.获取cookie数据用于身份认证
    # 代码层面任何判断用户是否登录
    
  • json格式数据

    json格式字符串数据使用的都是双引号
    json格式数据能够打破语言限制 实现不同编程语言之间的数据交互
    
    dumps		序列化
    loads		反序列化
    
    dump		序列化(文件)
    load		反序列化(文件)
    
  • 获取较大数据

    res = request.get(url,stream = True)
    for line in res.iter_content(): # 按行读取数据
        pass
    
  • 防爬措施及解决策略(重要)

    1.检验是否是浏览器
    	请求头里面添加相应的键值对即可
    2.检验当前请求来源
    	请求头里面添加相应的键值对即可
    3.IP代理池
    	requests.get(url,proxies={})
    4.cookie代理池
    	requests.get(url,cookies={})
    # 后续还会学习更多更加复杂的防爬措施
    
  • 解析库之bs4模块

    简单的理解为内部封装了正则表达式的用于快速帮你筛选数据的模块
    pip3 install beautifulsoup4
    pip3 install lxml  # 对应的解析器
    
    
    from bs4 import BeautifulSoup
    soup = BeautifulSoup('网页数据','lxml')
    
    soup.标签名  # 获取页面上从上往下第一个对应的标签
    soup.标签名.attrs  # 获取标签内部所有的属性
    soup.标签名.text  # 获取标签内部的文本数据
    soup.find(name='标签名')  # 获取页面上从上往下第一个对应的标签
    soup.find_all(name='标签名')  # 获取页面上所有对应的标签
    """
    标签之间的关系  主要是通过是否在内部来决定
    """
    

今日内容概要

  • bs4模块查找标签详细操作
  • 爬取红牛分公司数据
  • 爬取天气数据
  • 爬取链家二手房数据
  • 更多实战案例(知识点直接在案例中讲解)

今日内容详细

bs4模块查找标签详细操作

# 四种过滤器
#1.1、字符串:即标签名
# print(soup.find_all('b'))
#1.2、正则表达式
# import re
# print(soup.find_all(re.compile('^b'))) #找出b开头的标签,结果有body和b标签
#1.3、列表:如果传入列表参数,Beautiful Soup会将与列表中任一元素匹配的内容返回.下面代码找到文档中所有<a>标签和<b>标签:
# print(soup.find_all(['a','b']))
#1.4、True:可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
# print(soup.find_all(True))
# for tag in soup.find_all(True):
#     print(tag.name)  # for循环获取页面上所有的标签名称


find_all()

print(soup.find_all(name='a'))  
# name后面放标签名称即可  name参数也可以省略  		 print(soup.find_all('a'))

print(soup.find_all(attrs={'id':'link1'}))  # 查找属性中id=link1的标签

print(soup.find_all(attrs={'class':'title'}))  # 查看属性中class=title的标签

print(soup.find_all(attrs={'id':'link1','class':'title'}))  
# 也可以放多个键值对  是and关系

print(soup.find_all(id='link1'))  # 也可以直接书写属性名和属性值

print(soup.find_all(class_='title'))  
# 针对class不能直接书写 因为class是python的关键字

print(soup.find_all(name='a',class_='title'))  
# 查看a标签 但是必须具有class=title的a标签

print(soup.find_all('a',text='Lacie'))  
# 也可以根据标签内部的文本筛选标签  但是需要注意必须跟上其他的筛选条件

find与find_all用法一致 只不过find只找一个而已

css选择器

CSS选择器
1.标签选择器(通过标签名查找标签)
print(soup.select('a'))
2.id选择器(通过id值查找标签)
print(soup.select('#link1'))  # 查找id=link1的标签
'''css选择器针对id属性统一使用#代替'''

3.class选择器(通过class值查找标签)
print(soup.select('.title'))  # 查找class=title的标签
'''css选择器针对class属性统一使用.代替'''

print(soup.select('.story span'))  
# 查找class=story标签内部所有的span标签
'''css选择器空格表示后代'''
print(soup.select('.story>span'))   
# 查找class=story标签内部第一层级所有的span标签
'''css选择器大于号表示儿子'''

print(soup.select('#d1>.title'))  
# 查找id=d1标签内部第一层级class=title的标签
print(soup.select('#d1>.title span'))  
# 查找id=d1标签内部第一层级class=title的标签内部所有的span标签

爬取红牛分公司数据

import requests
import re
from bs4 import BeautifulSoup

1.尝试着直接朝地址发送请求 查看是否可以直接获取到相应的数据
res = requests.get(r'http://www.redbull.com.cn/about/branch') 'r取消转义'
print(res.status_code)  # 200
print(res.text)  # 有我们需要的内容
2.尝试着从html文本中筛选出我们需要的数据

# 方法一
'''正则表达式筛选'''
data = res.text
title_list = re.findall('<h2>(.*?)</h2>',data)      '添加(),进行分组优先展示'
addr_list = re.findall("<p class='mapIco'>(.*?)</p>",data)    
# 存在引号错误使用,需查看网页源码进行分别
email_list = re.findall("<p class='mailIco'>(.*?)</p>",data)
phone_list = re.findall("<p class='telIco'>(.*?)</p>",data)

# 打印展示
for i in range(len(title_list)):
    print("""
    公司名称:%s
    公司地址:%s
    公司邮箱:%s
    公司电话:%s
    """%(title_list[i],addr_list[i],email_list[i],phone_list[i]))
# 写入excel
import pandas as pd
data_dict = {'公司名称':title_list,'公司地址':addr_list,'公司邮箱':email_list,'公司电话':phone_list}
# 将字典转换成DataFrame
df = pd.DataFrame(data_dict)
# 利用DataFrame内置方法直接导出到excel表格
df.to_excel(r'company.xlsx')

# 方法二
'''bs4模块筛选'''
soup = BeautifulSoup(res.text,'lxml')
# find_all select
print(soup.find_all(name='h2'))
# print(soup.select('h2'))

title_list = soup.select('h2')  # [标签1、标签2...]
addr_list = soup.select('.mapIco')  # soup.find_all('p',class_='mapIco')
email_list = soup.select('.mailIco')
phone_list = soup.select('.telIco')
for i in range(len(title_list)):
    print("""
     公司名称:%s
     公司地址:%s
     公司邮箱:%s
     公司电话:%s
     """%(title_list[i].text,addr_list[i].text,email_list[i].text,phone_list[i].text))
'一个个筛选列表里的相应文本'

爬取链家二手房

地理位置如何确定?  			通过地区拼音首字母
https://sh.lianjia.com/ershoufang/		上海
https://bj.lianjia.com/ershoufang/		北京
https://sz.lianjia.com/ershoufang/		深圳
更加详细的区域如何确定?	  通过区级完整拼音
https://sh.lianjia.com/ershoufang/jiading/		嘉定
https://sh.lianjia.com/ershoufang/pudong/		浦东
https://sh.lianjia.com/ershoufang/jinshan/		金山

遇到多页数据的我们的处理思路是先研究单页之后再研究多页(很简单)

import requests
from bs4 import BeautifulSoup

# 1.直接发送get请求尝试是否可以获取到响应数据
res = requests.get('https://sh.lianjia.com/ershoufang/xuhui/')
# 2.研究页面布局筛选目标数据
soup = BeautifulSoup(res.text,'lxml')
# 研究发现所有的房屋信息都在一个固定的div里面
div_list = soup.find_all(name='div',attrs={'class':'info clear'})
# for循环获取每一个含有房屋所有信息的div标签并筛选出不同的部分
'''利用css选择器查找标签的时候 可以尽量写的精确一些 避免干扰'''
for div in div_list:
    print(div.select('.title a')[0].text)
    # print(div.select('.flood .positionInfo')[0].text)
    # print(div.select('.address .houseInfo')[0].text)
    # print(div.select('.followInfo')[0].text)
    # print(div.select('.priceInfo .totalPrice')[0].text)
    # print(div.select('.priceInfo .unitPrice')[0].text)
    print("""
    名称:%s
    地址:%s
    详情:%s
    关注:%s
    总价:%s
    单价:%s
    """%(div.select('.title a')[0].text,
         div.select('.flood .positionInfo')[0].text,
         div.select('.address .houseInfo')[0].text,
         div.select('.followInfo')[0].text,
         div.select('.priceInfo .totalPrice')[0].text,
         div.select('.priceInfo .unitPrice')[0].text
         ))

# 一行行获取地址,并将地址按分隔符'-',将地址分开
addr_l_list = soup.find_all(class_='positionInfo')
for l in addr_l_list:
    l = l.text
    print(l.split('-'))

# house_h_list = soup.find_all(class_='houseInfo')
# for h in house_h_list:
#     print(h.text)

# 一行行获取详情,并将详情按照分隔符'|',将详情分开
att1_list = soup.find_all(class_='houseInfo')
for h in att1_list:
    h = h.text
    print(h.split('|'))
# 分开关注情况
att2_list = soup.find_all(class_='followInfo')
for f in att2_list:
    f = f.text
    print(f.split('/'))
# 分开总价    
att3_list = soup.find_all(class_='totalPrice')
for t in att3_list:
    t = t.text
    print(t.split('|'))
    
    

作业

1.整理今日笔记
2.独立完成课上爬虫案例 
	分公司数据
    二手房数据
3.在作业2的基础之上完成数据导出到excel表格
	并且针对二手房数据完成多页爬取
4.自己查找其他感兴趣尝试爬取数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值