爬虫笔记1

.概念理解
1.爬虫是通过代码、模拟浏览器上网 然后抓取数据的过程 数据解析
2.爬虫是否合法
(1)法律允许
(2)有法律风险的

3.统一规定 【法律界限】
robots.txt协议
4.爬虫的分类:
(1)获取一整张页面 【通用爬虫】
(2)获取一整张页面 部分数据 【聚焦爬虫】
(3)检查页面更新、获取页面最新的更新的数据 【增量式爬虫】

5.爬虫的规则:
(1)反爬策略:门户网站 通过 技术手段 防止爬虫程序对页面爬取数据
(2)反 反爬策略:爬虫程序 通过 技术手段 对页面爬取数据

6.http 与https
service 与 client 进行数据交互的一种形式
request:
User-Agent: 请求载体的身份标识
response:
Content-Type:服务器响应client的数据类型

7.爬虫技术
(1)urllib 【老】
(2)requests 【好用】

定义:python自带的 基于网络请求的模块 功能强大 简单高效

功能:模拟浏览器发送请求

用法:
1.指定url
2.发送请求【get、post】
3.获取相应的数据
4.存储数据

安装
pip install requests
1
使用
(1) 通用爬虫
爬取百度首页
爬取百度首页

import requests
‘’’
整个html + html数据解析【数据解析没讲】 
获取部分html
‘’’
if name == ‘main’:
# 1.url
url = “https://www.baidu.com/”
# 2.发送请求
response = requests.get(url=url)
# 3.获取页面数据
response.encoding = “utf-8”
page_info = response.text
# 4.存储数据
with open(r"D:\sxwang\project\pycharm\python-sk\data\baidu.html", “w”, encoding=“utf-8”) as fp:
fp.write(page_info)

添加parms提交参数并提交headers进行伪装
import requests

‘’’
user -agent 检查:
门户网站检查 身份 【反爬机制】
ua 伪装: =》 【反 反爬机制】
‘’’
if name == ‘main’:
# 1.url
url = “https://www.sogou.com/web”
name = input(“输入一个搜索词:”)
parms = {
“query”: name
}

# ua 伪装 =》 模拟浏览器上网
headers = {
    "User-Agent": 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
}

# ua 伪装 =》 模拟浏览器上网
headers = {
    "User-Agent": 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
}

# 2.发送请求
response = requests.get(url=url, params=parms, headers=headers)
# 3.获取页面数据
response.encoding = "utf-8"
page_info = response.text

# 4.存储数据
with  open(f".\data\{name}.html", "w", encoding="utf-8") as fp:
    fp.write(page_info)
 

(2) 数据解析
1.为什么要进行数据解析?

答:为了获取指定的页面数据。
1
2.数据解析分类

1.正则 【了解】
2.bs4
3.xpath 【重要】 scrapy

3.解析的数据有哪些?

1.数据源:html
2.文本 或者 图片 html标签里面 或者 标签的属性

4.如何解析?

1.标签定位
2.解析数据

5.聚焦爬虫

1.指定url
2.发起请求
3.获取相应数据
4.数据解析
5.存储数据

(3) bs4
数据解析的工具

1.原理:

1.标签定位
2.解析数据

2.使用:

// 安装
pip install bs4 -i https://pypi.douban.com/simple

知识点概况
// 具体使用
from bs4 import BeautifulSoup
‘’’
实例化bs4类 BeautifulSoup => 加载 html
调用api 标签定位+ 解析数据
‘’’
if name == ‘main’:
# ua 伪装 =》 模拟浏览器上网
headers = {
“User-Agent”: 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ’
'Chrome/98.0.4758.102 Safari/537.36 ’
}

fp = open("lol.html", "r", encoding="utf-8")
soup = BeautifulSoup(fp, "lxml")  # 加载数据 :数据 + 格式

# 1.通过标签 解析文本
'''
    soup.tagname 
        :返回 html中 第一次出现的标签 内容
'''
# print(soup.div)
# print(soup.a)

# 2.find
'''
    soup.find 
        :1.soup.div => 返回 html中 第一次出现的标签 内容
        :2. 标签属性定位 eg:soup.find('div', class_='adc')
'''
# print(soup.find('div'))
# print(soup.find('div', class_='adc'))
# print(soup.find('a', title='凯南'))

# 3.find_all
'''
    soup.find_all 
        :1.取出 html中所有 tabname的内容
'''
# print(soup.find_all('a'))

# 4.select
'''
html:传值 
        id class 
    soup.select 
        :1. 标签属性值定位 想要的tab数据
        :2. 层级选择
'''
# print(soup.select(".adc"))
# print(soup.select(".adc > ul > li > a ")[0])
#
# # 5. 取文本数据
# print(soup.select(".adc > ul > li > a ")[0].text)
# #6. 取属性值
# print(soup.select(".adc > ul > li > a ")[0]['title'])
# print(soup.select(".adc > ul > li > a ")[0]['href'])
# print(soup.select(".adc > ul > li > a ")[0]['target'])

# print(soup.find('div', class_='adc'))
# print(soup.find('div', class_='adc').text)
print(soup.select(".adc > ul > li > a "))

for el in soup.select(".adc > ul > li > a "):
    print(el.text)
    print(el["title"])

fp = open("lol.html", "r", encoding="utf-8")
soup = BeautifulSoup(fp, "lxml")  # 加载数据 :数据 + 格式

# 1.通过标签 解析文本
'''
    soup.tagname 
        :返回 html中 第一次出现的标签 内容
'''
# print(soup.div)
# print(soup.a)

# 2.find
'''
    soup.find 
        :1.soup.div => 返回 html中 第一次出现的标签 内容
        :2. 标签属性定位 eg:soup.find('div', class_='adc')
'''
# print(soup.find('div'))
# print(soup.find('div', class_='adc'))
# print(soup.find('a', title='凯南'))

# 3.find_all
'''
    soup.find_all 
        :1.取出 html中所有 tabname的内容
'''
# print(soup.find_all('a'))

# 4.select
'''
html:传值 
        id class 
    soup.select 
        :1. 标签属性值定位 想要的tab数据
        :2. 层级选择
'''
# print(soup.select(".adc"))
# print(soup.select(".adc > ul > li > a ")[0])
#
# # 5. 取文本数据
# print(soup.select(".adc > ul > li > a ")[0].text)
# #6. 取属性值
# print(soup.select(".adc > ul > li > a ")[0]['title'])
# print(soup.select(".adc > ul > li > a ")[0]['href'])
# print(soup.select(".adc > ul > li > a ")[0]['target'])

# print(soup.find('div', class_='adc'))
# print(soup.find('div', class_='adc').text)
print(soup.select(".adc > ul > li > a "))

for el in soup.select(".adc > ul > li > a "):
    print(el.text)
    print(el["title"])
 


(4) xpath—数据解析的工具 [推荐]

知识点概况
import requests
from lxml import etree
if name == ‘main’:
# 1.实例化
root = etree.parse("\data\lol.html")

# 2.调用api
'''
    编写xpath表达式:
        1.标签定位
        2.数据解析
'''

'''
1.标签定位: 
    1.绝对路径
    2.相对路径
    3.属性定位
    4.索引定位
'''
# api:1 => 绝对路径 => 返回 Element list
t_info = root.xpath('/html/head/title')
print(t_info)

# api:2 => 相对路径 => // 可以从任何位置定位
t_info1 = root.xpath('//title')
print(t_info1)
t_info2 = root.xpath('/html//title')
print(t_info2)

# api:3 => 属性定位 => 标签[@属性="xxx"]
div = root.xpath('//div')
print(div)
div_adc = root.xpath('//div[@class="adc"]')
print(div_adc)

li_list = root.xpath('//div[@class="adc"]/ul/li')
print(li_list)

# api:4 => 索引定位 => 索引下标从1 开始  标签[索引]
li_list1 = root.xpath('//div[@class="adc"]/ul/li[1]')
print(li_list1)
li_list2 = root.xpath('//div[@class="adc"]/ul/li')[0]
print(li_list2)

a_list1 = root.xpath('//div[@class="adc"]/ul/li[1]/a')
print(a_list1)
a_list2 = root.xpath('//div[@class="adc"]//li[1]/a')
print(a_list2)

'''
2.数据解析: 
    1.标签文本
    2.标签属性
'''

# 1.文本
a_text = root.xpath('//div[@class="adc"]//li[1]/a/text()')
print(a_text)

li1_text = root.xpath('//div[@class="adc"]//li[1]//text()')
print(li1_text)

# 2.属性解析 => 标签/@属性名
img_info = root.xpath('//div[@class="top"]//img')
print(img_info)

img = root.xpath('//div[@class="top"]//img/@src')
print(img)

# 2.调用api
'''
    编写xpath表达式:
        1.标签定位
        2.数据解析
'''

'''
1.标签定位: 
    1.绝对路径
    2.相对路径
    3.属性定位
    4.索引定位
'''
# api:1 => 绝对路径 => 返回 Element list
t_info = root.xpath('/html/head/title')
print(t_info)

# api:2 => 相对路径 => // 可以从任何位置定位
t_info1 = root.xpath('//title')
print(t_info1)
t_info2 = root.xpath('/html//title')
print(t_info2)

# api:3 => 属性定位 => 标签[@属性="xxx"]
div = root.xpath('//div')
print(div)
div_adc = root.xpath('//div[@class="adc"]')
print(div_adc)

li_list = root.xpath('//div[@class="adc"]/ul/li')
print(li_list)

# api:4 => 索引定位 => 索引下标从1 开始  标签[索引]
li_list1 = root.xpath('//div[@class="adc"]/ul/li[1]')
print(li_list1)
li_list2 = root.xpath('//div[@class="adc"]/ul/li')[0]
print(li_list2)

a_list1 = root.xpath('//div[@class="adc"]/ul/li[1]/a')
print(a_list1)
a_list2 = root.xpath('//div[@class="adc"]//li[1]/a')
print(a_list2)

'''
2.数据解析: 
    1.标签文本
    2.标签属性
'''

# 1.文本
a_text = root.xpath('//div[@class="adc"]//li[1]/a/text()')
print(a_text)

li1_text = root.xpath('//div[@class="adc"]//li[1]//text()')
print(li1_text)

# 2.属性解析 => 标签/@属性名
img_info = root.xpath('//div[@class="top"]//img')
print(img_info)

img = root.xpath('//div[@class="top"]//img/@src')
print(img)
 


动手实验
import requests
from lxml import etree
if name == ‘main’:
# ua 伪装 =》 模拟浏览器上网
headers = {
“User-Agent”: ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36’
}

url = "https://dl.58.com/ershoufang"

# 1.通用爬虫
page_info = requests.get(url, headers=headers)

# 2.数据解析
root = etree.HTML(page_info.text)

# 3.标签定位
div_list = root.xpath('//section[@class="list"]/div')

fp = open(".\data\二手房.txt", "w", encoding="utf-8")
for div in div_list:
    # 标签定位
    title = div.xpath('./a/div[@class="property-content"]/div[@class="property-content-detail"]'
                      '/div[@class="property-content-title"]/h3/text()')[0]
    fp.write(title + "\n")
    print(title, "=>爬虫ok")

url = "https://dl.58.com/ershoufang"

# 1.通用爬虫
page_info = requests.get(url, headers=headers)

# 2.数据解析
root = etree.HTML(page_info.text)

# 3.标签定位
div_list = root.xpath('//section[@class="list"]/div')

fp = open(".\data\二手房.txt", "w", encoding="utf-8")
for div in div_list:
    # 标签定位
    title = div.xpath('./a/div[@class="property-content"]/div[@class="property-content-detail"]'
                      '/div[@class="property-content-title"]/h3/text()')[0]
    fp.write(title + "\n")
    print(title, "=>爬虫ok")
 


Tip
xpath路径 可以通过 检查窗口 右键 标签获取
(5) scrapy
概述
An open source and collaborative framework for extracting the data you need from websites.In a fast, simple, yet extensible way.
1.开源的爬虫框架
2.快速、简单、高效的方式

安装部署
pip install scrapy

基本使用
创建项目

scrapy startproject projectName

项目目录:

scrapy.cfg 【项目的配置文件】
settings.py 【项目的配置文件】
spiders/ 【防止 爬虫代码的目录】
编写爬虫代码

创建一个爬虫代码

scrapy genspider [options] <name> <domain>

scrapy genspider python01 www.xxx.com
'''
name:
    1.不能重复
    2.爬虫文件的名字
'''
name = 'python01'
'''
   scrapy 允许爬取的 url 
'''
allowed_domains = ['www.baidu.com']
'''
    scrapy 去爬取的 url 列表
'''
start_urls = ['http://www.baidu.com/','https://www.sougou.com']

scrapy genspider [options] <name> <domain>

scrapy genspider python01 www.xxx.com
'''
name:
    1.不能重复
    2.爬虫文件的名字
'''
name = 'python01'
'''
   scrapy 允许爬取的 url 
'''
allowed_domains = ['www.baidu.com']
'''
    scrapy 去爬取的 url 列表
'''
start_urls = ['http://www.baidu.com/','https://www.sougou.com']
 


3.启动爬虫项目
启动命令

    scrapy runspider [options] <spider_file>

    scrapy runspider ./test_scrapy/spiders/python01.py

    scrapy crawl python01

    scrapy crawl python01 --nolog 【使用命令 不显示日志信息】

数据解析

1.标签定位:
返回 selector(xpath,data[xpath表达式 结果])
2.数据解析
返回 selector(xpath,data[xpath表达式 结果])
3.取值
.get()
.getall()

存储数据【持久化数据】

scrapy crawl python01 -o ./sanguo.txt 【不支持txt格式】
支持:‘json’, ‘jsonlines’, ‘jl’, ‘csv’, ‘xml’, ‘marshal’, 'pickle’等

    scrapy runspider [options] <spider_file>

    scrapy runspider ./test_scrapy/spiders/python01.py

    scrapy crawl python01

    scrapy crawl python01 --nolog 【使用命令 不显示日志信息】
 

实例
settings 配置项说明

是否遵循robots.txt 的规则

ROBOTSTXT_OBEY = False

设备伪装

USER_AGENT = “”

爬取结果字符集设置,可以解决爬取结果中文乱码问题

FEED_EXPORT_ENCODING = ‘utf-8’

项目结构

主文件

import scrapy

class Python01Spider(scrapy.Spider):
name = ‘python01’
# allowed_domains = [‘www.xxx.com’]
start_urls = [‘https://dl.58.com/chuzu/’]

def parse(self, response):
    result = []
    # with open(r"D:\SystemLocal\Desktop_191204112\test_scrapy\data\58tc.html", 'wb') as f:
    #     f.write(response.body)cs
    inforList = response.xpath('//div[@class="list-wrap"]/div[@class="list-box"]/ul[@class="house-list"]/li['
                               '@class="house-cell realverify"]')

    for i in inforList:

        tmp = {
            'title': i.xpath(".//h2//a/text()").get().strip().replace(' ', '').replace('\n', '').replace('\r', ''),

            'room': i.xpath(".//p[@class='room']/text()").get().strip().replace(' ', '').replace('\n', '').replace(
                '\r', '').replace(' ', ''),

            'area': (i.xpath("./div[2]/p[2]/a[1]/text()").get() + i.xpath("./div[2]/p[2]/a[2]/text()").get())
                .strip().replace(' ', '').replace('\n', '').replace('\r', '').replace(' ', ''),

            'money': i.xpath(".//div[@class='money']/b[@class='strongbox']/text()").get() + "元/月"

        }  # 临时存放数据

        result.append(tmp)
    return result

def parse(self, response):
    result = []
    # with open(r"D:\SystemLocal\Desktop_191204112\test_scrapy\data\58tc.html", 'wb') as f:
    #     f.write(response.body)cs
    inforList = response.xpath('//div[@class="list-wrap"]/div[@class="list-box"]/ul[@class="house-list"]/li['
                               '@class="house-cell realverify"]')

    for i in inforList:

        tmp = {
            'title': i.xpath(".//h2//a/text()").get().strip().replace(' ', '').replace('\n', '').replace('\r', ''),

            'room': i.xpath(".//p[@class='room']/text()").get().strip().replace(' ', '').replace('\n', '').replace(
                '\r', '').replace(' ', ''),

            'area': (i.xpath("./div[2]/p[2]/a[1]/text()").get() + i.xpath("./div[2]/p[2]/a[2]/text()").get())
                .strip().replace(' ', '').replace('\n', '').replace('\r', '').replace(' ', ''),

            'money': i.xpath(".//div[@class='money']/b[@class='strongbox']/text()").get() + "元/月"

        }  # 临时存放数据

        result.append(tmp)
    return result
 


爬取结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值