python爬虫笔记(2)

python爬虫笔记

记录时间:2021年1月31日

理论知识

1、数据解析

(1)分类

  • 正则
  • bs4
  • xpath(***)

 

(2)原理概述

  • 解析的局部文本内容都会在标签之间或者对应的属性中进行存储
  • 第一步:进行指定标签的定位
  • 第二步:标签或者标签对应的属性中存储的数据值进行提取

 

(3)编码流程

1、指定url

2、发起请求

3、获取响应数据

4、数据解析

5、持久化存储

 

实战部分

1、正则解析

需求1:爬取糗事百科中糗图板块下热图图片

如何爬取图片数据?

当我们用requests发送请求后,我们可以获得响应response,其中:

  • response.text——字符串
  • response.content——二进制
  • json()——对象类型

保存图片就可以用response.content存储二进制形式的数据。

爬取单独1页内容:

import requests
import re
import os

if __name__ == '__main__':
    # 创建一个文件夹存储图片
    if not os.path.exists('./糗事百科'):
        os.mkdir('./糗事百科')
    url = 'https://www.qiushibaike.com/imgrank/'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
    }
    response = requests.get(url=url, headers=headers)
    html = response.text
    all_src = re.findall(
        '<div class="thumb">.*?<img src="(.*?)" alt=.*?</div>',
        html, re.S)
    for src in all_src:
        # 拼接url
        url = 'http:' + src
        # 获取图片二进制
        img = requests.get(url=url, headers=headers).content
        # 生成图片名称
        img_name = src.split('/')[-1]
        # 生成图片路径
        img_path = './糗事百科/' + img_name
        # 保存图片
        with open(img_path,'wb') as fp:
            fp.write(img)
            print(img_name+'下载完成')

分页爬取:

import requests
import re
import os

if __name__ == '__main__':
    # 创建一个文件夹存储图片
    if not os.path.exists('./糗事百科'):
        os.mkdir('./糗事百科')
    base_url = 'https://www.qiushibaike.com/imgrank/page/%d/'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
    }
    for page_num in range(1, 11):
        # 每一页创建一个文件夹分别存储
        if not os.path.exists('./糗事百科/' + str(page_num)):
            os.mkdir('./糗事百科/' + str(page_num))
        newurl = format(base_url % page_num)
        html = requests.get(url=base_url, headers=headers).text
        all_src = re.findall(
            '<div class="thumb">.*?<img src="(.*?)" alt=.*?</div>',
            html, re.S)
        for src in all_src:
            # 拼接url
            url = 'http:' + src
            # 获取图片二进制
            img = requests.get(url=url, headers=headers).content
            # 生成图片名称
            img_name = src.split('/')[-1]
            # 生成图片路径
            img_path = './糗事百科/' + str(page_num) + '/' + img_name
            # 保存图片
            with open(img_path, 'wb') as fp:
                fp.write(img)
                print(img_name + '下载完成')

 

2、bs4解析

操作步骤:

  • 第一步:实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
  • 第二步:通过调用BeautifulSoup对象中相关的属性和方法进行标签定位和数据提取

BeautifulSoup对象中相关的属性和方法:

——假设soup = BeautifulSoup(html.text, 'lxml')

  • soup.tagName:返回的是html中第一次出现tagName的对应的标签,例如:soup.div
  • soup.find():
    (1) 括号内填写标签名,例如:soup.find('div'),结果同soup.div;
    (2)属性定位,例如:soup.find('div', class_/id/attr = 'xxx')
  • soup.find_all('tagName'):返回所有满足要求的标签(列表),例如:soup.find_all('div', class_/id/attr = 'xxx')
  • select:
    —soup.select('某种选择器 (id,class,标签。。。选择器)  '):返回一个列表
    —层级选择器:
           —soup.select(' .classname > ul > li > a'):">"表示的是一个层级
           —soup.select(' .classname > ul  a'):空格表示多个层级
  • 获取标签之间的文本数据:
    —soup.div.text   :可以获取某一标签下所有的文本内容
    —soup.div.string   :可以获取某一标签直系的文本内容
    —soup.div.get_text()  :可以获取某一标签下所有的文本内容
  • 获取标签中的属性值:
    —soup.a['href']:获取a标签中href属性的内容

需求2:爬取三国演义小说所有的标题和章节内容

import requests
from bs4 import BeautifulSoup

if __name__ == '__main__':
    url = 'https://www.shicimingju.com/book/sanguoyanyi.html'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
    }
    html = requests.get(url=url, headers=headers)
    html.encoding = html.apparent_encoding
    soup = BeautifulSoup(html.text, 'lxml')
    titles = soup.select('.book-mulu > ul > li')
    for title in titles:
        print(title.a.text)
        book_url = 'https://www.shicimingju.com' + title.a['href']
        html = requests.get(url=book_url, headers=headers)
        html.encoding = html.apparent_encoding
        book_soup = BeautifulSoup(html.text, 'lxml')
        text = book_soup.find('div', class_='chapter_content').text.replace(' ', '')
        # print(text)
        with open('./三国演义/三国演义.txt', 'a', encoding='utf-8') as fp:
            fp.write(title.a.text + text + '\n\n')

 

3、xpath解析

最常用且最便捷高效的一种解析方式。

xpath解析原理:

  • 第一步:实例化一种etree的对象,且需要将被解析的页面源码数据加载到该对象中。
  • 第二步:调用etree对象中的xpath方法结合xpath表达式实现标签的定位和内容的捕捉

xpath表达式:

  • '/html/body/div'  :定位到html下body的div标签
  • '/html//div'  :定位到html下多个层级的div标签
  • '//div'  :定位到所有的div标签
  • '//div[@class=xxx]'  :定位到class为“xxx"的div标签
  • '//div[@class=xxx]/p[3]'  :定位到class为“xxx"的div的第3个p标签(索引是从1开始
  • 取文本:
    —'/text()'  :取直系文本
    —'//text()'  :取所有文本
  • 取属性:
    —'/@attrName'  :例如'//div//img/@src',获取div下img的src属性

需求3:爬取58二手房中的房源信息

import requests
from lxml import etree

if __name__ == '__main__':
    url = 'https://www.58.com/ershoufang/'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
    }
    html = requests.get(url=url, headers=headers)
    tree = etree.HTML(html.text)
    # print(html.text)
    tr_list = tree.xpath('//*[@id="global"]/table/tr')
    for tr in tr_list:
        msg = tr.xpath('./td[2]/a/text()')[0]
        price = tr.xpath('./td[3]/b/text()')[0] + '万元'
        type_ = tr.xpath('./td[4]//text()')[0]+tr.xpath('./td[4]//text()')[1]
        size = tr.xpath('./td[5]/b/text()')[0] + '平方米'
        with open('./二手房/房源信息.txt', 'a', encoding='utf-8') as fp:
            fp.write(msg + ' ' + price + ' ' + type_ + ' ' + size + '\n')
    print('保存成功!')

需求4:爬取4k高清图片

通用处理中文乱码的方法:

  • img_name.encode('iso-8859-1').decode('gbk')
  • response.encoding='utf-8'
import requests
from lxml import etree

if __name__ == '__main__':
    url = 'http://pic.netbian.com/4kfengjing/'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
    }
    html = requests.get(url=url, headers=headers)
    tree = etree.HTML(html.text)
    li_list = tree.xpath('//ul[@class="clearfix"]//li')
    for li in li_list:
        url = 'http://pic.netbian.com' + li.xpath('./a/img/@src')[0]
        filename = li.xpath('./a/b/text()')[0].encode('iso-8859-1').decode('gbk') + '.jpg'
        data = requests.get(url=url, headers=headers).content
        with open('./风景图片/'+filename,'wb')as fp:
            fp.write(data)
            print(filename+'保存成功!')

需求5:爬取全国城市名称

import requests
from lxml import etree

if __name__ == '__main__':
    url = 'https://www.aqistudy.cn/historydata/'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56'
    }
    html = requests.get(url=url, headers=headers)
    tree = etree.HTML(html.text)
    ul_list = tree.xpath('//div[@class="all"]/div[@class="bottom"]/ul[@class="unstyled"]')
    with open('./全国城市名称/全国城市名称.txt', 'a', encoding='utf-8') as fp:
        for ul in ul_list:
            index = ul.xpath('./div[1]/b//text()')[0]
            fp.write(index+'\n')
            li_list = ul.xpath('./div[2]/li')
            for li in li_list:
                city = li.xpath('./a/text()')[0]
                fp.write(city + ' ')
            fp.write('\n')
    print('保存成功!')

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加油呀兄弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值