day01
  • 爬取糗图图片数据

  • 爬取优美图库高清图片

  • 爬取梨视频视频数据

  • 防爬措施之防盗链

爬取糗图图片数据

思路

1.发送get请求获取页面数据
2.利用bs4解析
3.研究标签特征 获取图片链接
3.1进行for循环拿到图片完整的地址
3.2发送请求保存数据
4.利用上述代码自定义成函数
5.给到实参获取多页图片数据

完整代码

一周内容回顾(9.22-9.24)_ide一周内容回顾(9.22-9.24)_ide_02
import requests
from bs4 import BeautifulSoup
import os

if not os.path.exists(r'糗图图片'):
    os.mkdir(r'糗图图片')


def get_img(url):
    # 1.发送get请求获取页面数据
    res = requests.get(url)
    # 2.解析库bs4
    soup = BeautifulSoup(res.text, 'lxml')
    # 3.研究标签特征 获取图片链接
    img_tag_list = soup.find_all(name='img', attrs={'class': 'illustration'})
    for img in img_tag_list:
        img_src = img.get('src')
        full_src = 'https:' + img_src
        # 朝图片完整的地址发送请求保存数据
        res1 = requests.get(full_src)
        img_name = full_src.rsplit('/')[-1]
        file_path = os.path.join(r'糗图图片', img_name)
        with open(file_path, 'wb') as f:
            f.write(res1.content)
        print('图片:%s 保存成功' % img_name)


for i in range(1, 5):
    base_url = "https://www.qiushibaike.com/imgrank/page/%s/" % i
    get_img(base_url)
View Code

 

爬取优美图库高清大图

思路

1.朝主页面发送get请求
2.获取二次详情页地址链接
3.由于页面上有很多列表标签 我们需要先进行区分 所以先找上一层div标签
4.先获取所有的li标签
5.for循环一个个li标签 获取内部a标签
6.提前定义根目录地址
7.朝一个个链接地址发送请求
8.筛选出页面上的图片src地址
9.朝高清图大图的地址发送请求获取图片数据
10.保存并写入文件

完整代码

一周内容回顾(9.22-9.24)_ide一周内容回顾(9.22-9.24)_ide_02
import requests
from bs4 import BeautifulSoup
import os

if not os.path.exists(r'优美图片库'):
    os.mkdir(r'优美图片库')

# 1.朝主页面发送get请求
res = requests.get('https://www.umei.cc/bizhitupian/diannaobizhi/')
'''当使用.text方法之前最好先确认一下页面数据是否乱码'''
res.encoding = 'utf-8'  # 容易忽略
# 2.获取二次详情页地址链接
soup = BeautifulSoup(res.text, 'lxml')
# 由于页面上有很多列表标签 我们需要先进行区分 所以先找上一层div标签
div_tag = soup.find(name='div', attrs={'class': 'TypeList'})
# 先获取所有的li标签
li_list = div_tag.find_all(name='li')  # ['li>a','li>a',...]
# for循环一个个li标签 获取内部a标签
# 提前定义根目录地址
base_url = 'https://www.umei.cc'
for li in li_list:
    a_tag = li.find(name='a')
    a_link = a_tag.get('href')
    a_full_link = base_url + a_link
    # 朝一个个链接地址发送请求
    res1 = requests.get(a_full_link)
    '''由于我们只需要链接 并且发现链接没有字符 全是英文 所以此处不需要考虑'''
    soup1 = BeautifulSoup(res1.text, 'lxml')
    # 筛选出页面上的图片src地址
    img_tag = soup1.select('div.ImageBody img')  # 列表
    for img in img_tag:
        src = img.get('src')
        # 朝图片的地址发送请求获取图片数据
        res2 = requests.get(src)
        file_path = os.path.join(r'优美图片库', src[-10:])
        with open(file_path, 'wb') as f:
            f.write(res2.content)
        print('图片:%s 下载成功' % file_path)
View Code

 

爬取梨视频单页数据

思路

1.先在空白处右键点击查看网页源代码
2.发现页面上的视频信息在网页中,该网站的视频链接、名称等是直接加载的
3.模拟向梨视频汽车板块网址发送get请求
4.分析返回结果发现视频链接是一个个li标签下的a标签的href值
5.由于同类li只用于存放视频,从这些li标签定位a标签即可
6.补全a标签中的链接,点击,是视频详情页,查询该网页源代码
7.视频详情页中视频不是直接加载的,无需向该网页发送请求
8.通过network找到二次加载的地址,并向其发送get请求,返回错误信息,说明该网站有防爬措施
9.在请求头中添加referer字段说明请求来源
10.向该视频链接发送请求并反序列化
11.拿到的视频链接无法访问
12.分析可知中间有一段被系统时间替换
13.利用视频编号将其替换回来从而获取真实连接
14.向该链接发送请求并将返回的视频保存至本地

完整代码

一周内容回顾(9.22-9.24)_ide一周内容回顾(9.22-9.24)_ide_02
import requests
from bs4 import BeautifulSoup
import os
import time

if not os.path.exists(r'视频'):
    os.mkdir(r'视频')
# 定义根目录地址
base_url = 'https://www.pearvideo.com/'

# 1.发送get请求获取页面数据
res = requests.get('https://www.pearvideo.com/category_31')
# 2.使用bs4模块解析
soup = BeautifulSoup(res.text, 'lxml')
# 3.研究视频详情链接
li_list = soup.select('li.categoryem')
# 4.循环获取每个li里面的a标签
for li in li_list:
    a_tag = li.find(name='a')
    a_href_link = a_tag.get('href')  # video_1742158
    # 通过研究发现详情页数据是动态加载的 所以通过network获取到地址
    video_id = a_href_link.split('_')[-1]
    headers = {
        "Referer": "https://www.pearvideo.com/video_%s" % video_id
    }
    res1 = requests.get('https://www.pearvideo.com/videoStatus.jsp',
                        params={'contId': video_id},
                        headers=headers
                        )
    time.sleep(1)
    data_dict = res1.json()
    src_url = data_dict['videoInfo']['videos']['srcUrl']
    systemTime = data_dict['systemTime']
    real_url = src_url.replace(systemTime, 'cont-%s' % video_id)
    res2 = requests.get(real_url)
    file_path = os.path.join('视频', real_url[-12:])
    with open(file_path, 'wb')as f:
        f.write(res2.content)
    print('%s成功' % file_path)
View Code

多页操作完整代码

一周内容回顾(9.22-9.24)_ide一周内容回顾(9.22-9.24)_ide_02
梨视频多页数据爬取思路
import requests
from bs4 import BeautifulSoup
import os
import time

if not os.path.exists(r'梨视频数据'):
    os.mkdir(r'梨视频数据')


def get_video(n):
    res = requests.get('https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=31&start=%s' % n)
    soup = BeautifulSoup(res.text, 'lxml')
    li_list = soup.select('li.categoryem')
    # 4.循环获取每个li里面的a标签
    for li in li_list:
        a_tag = li.find(name='a')
        a_href_link = a_tag.get('href')  # video_1742158
        video_id = a_href_link.split('_')[-1]
        # 防盗链
        headers = {
            "Referer": "https://www.pearvideo.com/video_%s" % video_id
        }
        res1 = requests.get('https://www.pearvideo.com/videoStatus.jsp',
                            params={'contId': video_id},
                            headers=headers
                            )
        data_dict = res1.json()
        src_url = data_dict['videoInfo']['videos']['srcUrl']
        systemTime = data_dict['systemTime']
        real_url = src_url.replace(systemTime, 'cont-%s' % video_id)

        res2 = requests.get(real_url)
        file_path = os.path.join(r'梨视频数据', '%s.mp4' % video_id)
        with open(file_path, 'wb') as f:
            f.write(res2.content)
        time.sleep(0.5)


for n in range(12, 48, 12):
    get_video(n)
View Code

 

防爬措施之防盗链

# 校验当前请求从何而来 如果是本网站则允许访问如果是其他网址则拒绝
在请求头中有一个专门用于记录从何而来的键值对referer

 

day02
  • openpyxl模块

  • 创建文件
  • 写数据
  • 读数据

openpyxl模块

# 在python能够操作excel表格的模块
    1.openpyxl模块
            该模块可以操作03版本的之后的文件
            针对03版本之前的兼容性可能不太好
    2.xlrd、xlwt模块
            xlrd控制读文件 xlwt控制写文件
            该模块可以操作任何版本的excel文件

创建文件

from openpyxl import Workbook

# 1.创建一个对象
wb = Workbook()


# 2.保存文件
wb.save(r'aaa.xlsx')

创建多个工作簿

wb1 = wb.create_sheet('学生表')
wb2 = wb.create_sheet('工作表')

w3 = wb.create_sheet('老师表', 0)
w3.title = '教师表'  # 工作簿名称支持二次修改

如何写入数据

1.wb1['单元格位置'] =2.wb1.cell(column=1, row=3, value=333)  # cell意思是单元格
3.wb1.append(['序号', '姓名', '年龄', '性别'])  # 定义表头数据
  wb1.append([1, 'Ben', 28, 'male'])  # 存储表单数据

如何读数据

from openpyxl import load_workbook

wb = load_workbook(r'xxx.xlsx', data_only=True)
print(wb.sheetnames) 
1.wb1 = wb['工作簿名']  
print(wb1['单元格位置'].value)  # 获取数据
2.
print(wb1.cell(row=3, column=2).value)

获取每行每列数据

for row in wb1.rows:
     for r in row:
         print(r.value)

for col in wb1.columns:
    for c in col:
        print(c.value)


# 获取最大的行数和列数
print(wb1.max_row)  
print(wb1.max_column)  
  day03
  • 爬取豆瓣电影Top250
  • 爬取链家二手房数据
  • 爬取汽车之家新闻数据

爬取豆瓣电影Top250

完整代码

一周内容回顾(9.22-9.24)_ide一周内容回顾(9.22-9.24)_ide_02
import requests
import re
import time
from bs4 import BeautifulSoup
from openpyxl import Workbook

'''
万变不离其宗第一步总归是观察网页 从第一页开始先不要想分页就先爬一页
1.看第一页的数据加载方式
2.是直接加载的那就可以直接下手爬网站了
'''

wb = Workbook()  # 打开表格
wb1 = wb.create_sheet('豆瓣表格', 0)  # 定义好工作簿
wb1.append(['电影名', '导演', '主演', '评分', '评价人数', '短评'])  # 插入表头


def movie_rank(n):
    url = 'https://movie.douban.com/top250'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'}
    res = requests.get(url,
                       headers=headers,
                       params={'start': n})  # 通过n控制页数
    net = res.text  # 转文本方便解析
    soup = BeautifulSoup(net, 'lxml')
    title_list = re.findall('<img width="100" alt="(.*?)" src=', net)  # 正则爬电影名
    direct_list = re.findall('导演: (.*?)&nbsp;&nbsp;&nbsp;', net)  # 正则爬导演
    actor_list = re.findall(' &nbsp;&nbsp;&nbsp;主演: (.*?) /...', net)  # 正则爬主演
    score_list = re.findall('property="v:average">(.*?)</span>', net)  # 正则爬评分
    comment_count_list = re.findall('<span>(.*?)人评价</span>', net)  # 正则爬短评
    li_list = soup.select('ol.grid_view>li')  # 拿到短评所在标签外部li标签的列表缩小范围方便进一步操作
    inq_list = []  # 定义空列表方便之后加
    for li in li_list:  # 取出一个个元素
        li = str(li)  # 把网页上的没有属性的东西转成字符串
        if '<span class="inq">' in li:  # 字符串包含运算
            inq_part = re.findall('<span class="inq">(.*?)</span>', li)  # 有就可以正则拿到短评
            inq_list.append(inq_part[0])  # 拿到后取出元素写入
        else:
            inq_part = '暂无短评'  # 没有自己加一个字段
            inq_list.append(inq_part)  # 也写入列表
    full_info = zip(title_list, direct_list, actor_list, score_list, comment_count_list, inq_list)  # 整合成一起
    for i in full_info:  # 拿出里面的组合
        wb1.append(list(i))  # 转成列表写入
    time.sleep(10)  # 吸取被封ip的教训停久点


for n in (0, 225, 25):  # 翻页规律控制
    movie_rank(n)  # 把实参给函数

wb.save(r'豆瓣top250.xlsx')  # 别忘了最后保存
View Code

 

爬取链家二手房数据

思路

1、进入链接二手房某个区的界面,判断分析该数据的加载方式,结果的知识直接加载的
2、在pycharm中打印下看看是否有防爬和乱码现象,结果是没有,那对页面进行数据解析筛选
3、在页面空白处右键点击检查,利用鼠标选中标题查询该数据在哪个标签里,并研究如何获取
4、然后循环每一个li标签,再去筛选一个个需要的数据
5、多页操作可去浏览器点击下一页查看数据,分析得知根据后缀page来定义参数
6、封装成函数,调用即可完成多页获取数据操作
7、利用openpyxl模块将数据写入excel表格中

完整代码

一周内容回顾(9.22-9.24)_ide一周内容回顾(9.22-9.24)_ide_02
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook

wb = Workbook()
wb1 = wb.create_sheet('二手房数据')
# 先定义表头
wb1.append(['房屋名称', '详情链接', '小区名称', '区域名称', '详细信息', '关注人数', '发布时间', '总价', '单价'])


def get_info(num):
    res = requests.get('https://sh.lianjia.com/ershoufang/pudong/pg%s/' % num)
    soup = BeautifulSoup(res.text, 'lxml')
    li_list = soup.select('ul.sellListContent>li')
    for li in li_list:
        a_tag = li.select('div.title>a')[0]
        # 房屋名称
        title = a_tag.text
        # 详情链接
        link = a_tag.get('href')
        div_tag = li.select('div.positionInfo')[0]
        # 地址信息
        address = div_tag.text  # xxx - xxx
        res = address.split('-')
        if len(res) == 2:
            xq_name, xq_pro = res
        else:
            xq_name = xq_pro = res[0]
        div_tag1 = li.select('div.houseInfo')[0]
        # 详细信息
        info = div_tag1.text
        div_tag2 = li.select('div.followInfo')[0]
        # 关注度及发布时间
        focus_time = div_tag2.text  # xxx / xxx
        people_num, publish_time = focus_time.split('/')
        div_tag3 = li.select('div.totalPrice')[0]
        # 总价
        total_price = div_tag3.text
        div_tag4 = li.select('div.unitPrice')[0]
        # 单价
        unit_price = div_tag4.text
        
        #写入数据
        wb1.append(
            [title, link, xq_name.strip(), xq_pro.strip(), info, people_num.strip(), publish_time.strip(), total_price,
             unit_price])


for i in range(1, 5):
    get_info(i)

wb.save(r'链家浦东二手房数据.xlsx')
View Code

 

爬取汽车之家新闻数据

思路

明确获取新闻数据有哪些:
    新闻标题 新闻链接 新闻图标 发布时间 新闻简介

1.网页加载的方式虽然下滑到底会有新加载但是并没有请求从网站发出
    这种也算动态加载吧 但是没有别的请求发出 是通过写好的js请求实现的
    对于这种加载方式就直接把它看作是直接写在页面上的就好了

2.页面干扰问题
    就是在正常的网页布局一面加了些没用的东西游离在常规规律之外
    让你爬起来没这么舒服 但是这个解决方法只要加上一个if判断就能避开

完整代码

一周内容回顾(9.22-9.24)_ide一周内容回顾(9.22-9.24)_ide_02
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook

wb = Workbook()
wb1 = wb.create_sheet(r'汽车之家新闻', 0)  # 创建工作簿
wb1.append(['标题', '链接', '图片链接', '更新时间', '详情', '浏览人数', '评论人数'])  # 插入表头


def net_page(n):  # 用来控制想要的页数  不过如果想要全爬下来就直接用for循环就行
    url = 'https://www.autohome.com.cn/all/%s/' % n
    return url  # 把具体网址反出去


url = net_page(input('请输入想要查看的页码'))  # 调用函数控制网页
res = requests.get(url,
                   headers={
                       'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'})
res.encoding = 'gbk'  # 查看网页编码后改成和网页一致
soup = BeautifulSoup(res.text, 'lxml')  # 解析
li_list = soup.select('div#auto-channel-lazyload-article li')  # 按照li标签分割出来 清晰思路

for li in li_list:  # for循环取到一个个li
    a_tag = li.find('a')  # 找到第一个a标签
    if not a_tag:  # 有页面干扰项所以要做个判定如果里面没有a标签那a_tag的返回结果为空
        continue  # 通过取反然后直接跳过这个标签继续循环
    link = 'https:' + a_tag.get('href')  # 拼接标签里的网站获得详情页网址
    res1 = requests.get(link,
                        headers={
                            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'})
    soup1 = BeautifulSoup(res1.text, 'lxml')  # 解析详情页
    title = soup1.select('div#articlewrap>h1')[0].text  # 拿一下详情页标题
    img_link = 'https:' + li.select('div.article-pic>img')[0].get('src')
    publish_time = soup1.select('div.article-info>span.time')[0].text  
    detail = li.find('p').text  # 找到预览目录页的详情小字段
    view_count = li.select('span.fn-right>em')[0].text  # 获取浏览人数
    comment_count = li.select('span.fn-right>em')[1].text  # 获取评论数量
    wb1.append([title.strip(), link, img_link, publish_time.strip(), detail, view_count, comment_count])  # 插入表格
    
wb.save(r'汽车之家.xlsx')  # 保存表格
View Code