基于request的爬虫练习
引言
概述
概念:基于网络请求的模块
作用:用来模拟浏览器发请求,从而实现爬虫
通用爬虫
步骤:
- 指定url
- 请求发送:get返回的是一个响应对象
- 获取响应数据: text返回的是字符串形式的响应数据
- 持久化存储
爬取搜狗首页的页面源码数据
1 |
import requests |
实现一个简易的网页采集器
- 请求参数动态化(自定义字典给get方法的params传参)
- 使用UA伪装
1 |
url = 'https://www.sogou.com/web' |
动态加载的数据
- 页面中想要爬取的内容并不是请求当前url得到的,而是通过另一个网络请求请求到的数据(例如,滚轮滑到底部,会发送ajax,对局部进行刷新)
例子:爬取豆瓣电影中动态加载出的电影详情
我们想爬取的页面是:豆瓣电影分类排行榜 - 科幻片 https://movie.douban.com/typerank?type_name=%E7%A7%91%E5%B9%BB&type=17&interval_id=100:90&action=
首先在chorme的抓包工具中进行全局搜索发现它不是请求当前url得到的,而是一个新的url:
https://movie.douban.com/j/chart/top_list?
当然这是一个ajax请求(在chorme的抓包工具中选择 XHR 可以进行查看)
在寻找另一部电影,请求的url仍然是
https://movie.douban.com/j/chart/top_list?
然后我们就需要找参数的规律了:
1
2
3
4
5
6
7
8
9
10
11type: 17
interval_id: 100:90
action:
start: 0
limit: 1
# 第二部
type: 17
interval_id: 100:90
action:
start: 20
limit: 20start 和 limit 是可以变化的,基于例二,我们自定义字典进行传参,然后进行尝试。
1 |
url = 'https://movie.douban.com/j/chart/top_list' |
note:response.json() 可以免除我们手动使用json进行loads的过程。
爬取肯德基的餐厅位置信息
地址为:
http://www.kfc.com.cn/kfccda/storelist/index.aspx
post请求
一次爬取多页数据
思路:
- 首先,数据是动态加载的,分析请求方式为 post 发出的 url 与 data。
- 通过pageSize就可以在循环内完成多所有地址的爬取。
1 |
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword' |
补充:可以使用代理服务器,如搜索:全网代理IP
中标公告提取
- 需求
https://www.fjggfw.gov.cn/Website/JYXXNew.aspx 福建省公共资源交易中心
提取内容:
工程建设中的中标结果信息/中标候选人信息
完整的html中标信息
第一中标候选人
中标金额
中标时间
其它参与投标的公司
思路:
- 从首页打开一个公告,先尝试得到一个公告的信息。
- 在得到另一个公告的信息进行比较,只有ID是变化的,所以有了ID就可以批量爬取了。
- 回到首页,判断加载方式,确定数据的请求方式,url以及参数。
实现过程:
- 确认爬取的数据都是动态加载出来的
- 在首页中捕获到ajax请求对应的数据包,从该数据包中提取出请求的url和请求参数
- 对提取到的url进行请求发送,获取响应数据(json),(包含ID信息)
- 从json串中提取到每一个公告对应的id值
- 将id值和中标信息对应的url进行整合,进行请求发送捕获到每一个公告对应的中标信息数据
1 |
# 该部分为得到一个公告的信息,但是我们这里的ID不灵活,需要进一步改进。 |
完成了对公告详情的爬取后,接下来批量爬取公告。
1 |
# 该部分完成了对前5页的公告信息进行爬取 |
爬取图片
如何做?
- 基于requests
- 基于urllib
- 区别:urllib中的 urlretrieve 不可以进行UA伪装
requests在urllib基础上产生,更加pythonic!
基于requests的图片爬取
1 |
import requests |
- request更具通用性,数据可以展示为:text(字符串),json(列表/字典),content(字节)。
基于urllib的图片爬取
1 |
# 基于urllib |
- 由于urlretrieve不能做UA伪装,所以存在图片缺失的可能。
聚焦爬虫
较通用爬虫相比,增加了数据解析。
数据解析
概念:将一整张页面的局部数据进行提取/解析
作用:用来实现聚焦爬虫
实现方式:
- 正则
- bs4
- xpath
- pyquery
数据解析的通用原理是什么?
- 标签的定位
- 数据的提取
页面中的相关的字符串的数据都存储在哪里?
- 标签中间
- 标签的属性中
基于聚焦爬虫的编码流程
- 指定url
- 发起请求
- 获取响应数据
- 数据解析
- 持久化存储
正则解析
爬取煎蛋网中的图片
- 地址为:
http://jandan.net/pic/MjAxOTEwMDktNjk=#comments
实现过程:
- 指定url
- 获取响应数据
- 数据解析
- 写正则表达式
- 正则匹配
- 持久化存储
1 |
import re |
note:内容依据响应数据page_text,而不是根据浏览器中网页上的代码,上面就出现一个字母的大小写不同而导致正则失效的例子。
bs4解析
环境的安装:
- pip install bs4
- pip install lxml
bs4的解析原理:
- 实例化一个BeatifulSoup的一个对象,把即将被解析的页面源码数据加载到该对象中
- 需要调用BeatifulSoup对象中的相关的方法和属性进行标签定位和数据的提取
BeatifulSoup的实例化
- BeatifulSoup(fp, ‘lxml’) 将本地存储的html文档中的页面源码数据加载到该对象中
- BeatifulSoup(page_text, ‘lxml’) 将从互联网中请求到的页面源码数据加载到该对象中
标签的定位
soup.tagName: 只可以定位到第一个tagName标签
属性定位:
- soup.find(‘div’,’attrName=’value’) 只能定位到符合要求的第一个
- soup.findAll:返回列表,可以定位到符合要求的所有标签
note:只有class需要加下划线,其它直接用原名就可以。
选择器定位:
- select(‘选择器’)
- 选择器:id,class,tag,层级选择器(大于号表示一个层级,空格表示多个层级)
取文本
- text:将标签中所有文本取出
- string:将标签中直系的文本取出
取属性
- tag[‘attrName’]
熟悉
此为练手的html。
1 |
<html lang="en"> |
熟悉 BeautifulSoup 的选择器以及如何取文本和属性
1 |
fp = open('./test.html',encoding='utf-8') |
爬取三国演义小说的标题和内容
- 地址为:
http://www.shicimingju.com/book/sanguoyanyi.html
数据解析流程:
- 首先定位标签
- 然后取出文本和内容
1 |
main_url = 'http://www.shicimingju.com/book/sanguoyanyi.html' |
xpath 解析
环境的安装
- pip install lxml
解析原理
- 实例化一个etree的对象,且把即将被解析的页面源码数据加载到该对象中
- 调用etree对象中的xpath方法结合着不同形式的xpath表达式进行标签定位和数据提取
etree对象的实例化
- etree.parse(‘fileName’)
- etree.HTML(page_text)
标签定位
- 最左侧的/:一定要从根标签开始进行标签定位
- 非最左侧的/:表示一个层级
- 最左侧的//:可以从任意位置进行指定标签的定位
- 非最左侧的//:表示多个层级
- 属性定位:
- //tagName[@attrName=”value”]
- 索引定位:
- //tagName[@attrName=”value”]/li[2],索引是从1开始的
- 逻辑运算:
- 找到href属性值为空且class属性值为du的a标签
- //a[@href=”” and @class=”du”]
- 模糊匹配:
- //div[contains(@class, “ng”)]
- //div[starts-with(@class, “ta”)]
取文本
- /text():取直系的文本内容
- //text():取所有文本内容
取属性
- /@attrName
note:
- 返回的都是列表
- 在google中的Element可以直接copy xpath
熟悉
依旧使用上面的html练手
1 |
from lxml import etree |
爬取虎牙主播名称,热度和标题
1 |
url = 'https://www.huya.com/g/xingxiu' |
爬取所有页码的妹子
地址为:http://pic.netbian.com/4kmeinv/
- 涉及中文乱码
- 以前对response的 encoding 这样代价大
iso-8859-1 –> utf-8 先编码成iso-8859-1 在解码成 utf或gbk
- 以前对response的 encoding 这样代价大
- 多页码数据的爬取
- 制定一个通用的url模板
基于request的爬虫练习的更多相关文章
- 基于golang分布式爬虫系统的架构体系v1.0
基于golang分布式爬虫系统的架构体系v1.0 一.什么是分布式系统 分布式系统是一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统.简单来说就是一群独立计算机 ...
- 爬虫,基于request,bs4 的简单实例整合
简单爬虫示例 爬取抽屉,以及自动登陆抽屉点赞 先查看首页拿到cookie,然后登陆要携带首页拿到的 cookie 才可以通过验证 """""" ...
- 爬虫学习之基于Scrapy的爬虫自动登录
###概述 在前面两篇(爬虫学习之基于Scrapy的网络爬虫和爬虫学习之简单的网络爬虫)文章中我们通过两个实际的案例,采用不同的方式进行了内容提取.我们对网络爬虫有了一个比较初级的认识,只要发起请求获 ...
- 基于 Electron 的爬虫框架 Nightmare
作者:William 本文为原创文章,转载请注明作者及出处 Electron 可以让你使用纯 JavaScript 调用 Chrome 丰富的原生的接口来创造桌面应用.你可以把它看作一个专注于桌面应用 ...
- 基于Nodejs的爬虫
简介 基于 Node.JS 爬取 博客园 1W+博文,对博文内容做关键词提取,生成词云. 演示 安装 安装 git.Node.JS.MongoDB.Yarn 克隆代码 git clone git@gi ...
- 基于python的爬虫(一)
抓取网页 python核心库 urllib2 实现对静态网页的抓取,不得不说,"人生苦短,我用python"这句话还是有道理的,要是用java来写,这估计得20行代码 (对不住了博 ...
- 基于.net的爬虫应用-DotnetSpider
最近应朋友的邀请,帮忙做了个简单的爬虫程序,要求不高,主要是方便对不同网站的爬取进行扩展,获取到想要的数据信息即可.当然,基于数据的后期分析功能是后话,以后的随笔我会逐步的介绍. 开源的爬虫框架比较多 ...
- 基于scrapy-redis分布式爬虫的部署
redis分布式部署 1.scrapy框架是否可以自己实现分布式? - 不可以.原因有二. 其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls ...
- 基于scrapy-redis分布式爬虫(简易)
redis分布式部署 1.scrapy框架是否可以自己实现分布式? - 不可以.原因有二. 其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls ...
随机推荐
- C++踩坑记录(一)std:;string的析构
之前写服务端程序有一个往消息队列里面推json的过程,然后发现推进去C#端取到的无论如何都是个空指针 简单复现一下现场 string str1 = string("hello1") ...
- Elasticsearch:运用scroll接口对大量数据实现更好的分页
在Elasticsearch中,我们可以通过size和from来对我们的结果来进行分页.但是对于数据量很大的索引,这是有效的吗?Scroll API可用于从单个搜索请求中检索大量结果(甚至所有结果), ...
- CF700E Cool Slogans——SAM+线段树合并
RemoteJudge 又是一道用线段树合并来维护\(endpos\)的题,还有一道见我的博客CF666E 思路 先把\(SAM\)建出来 如果两个相邻的串\(s_i\)和\(s_{i+1}\)要满足 ...
- [].slice.call(arguments,1) 个人理解
var arr = []; [] == arr; 假设 var arr = [1,2,3,4,5]; 那么 arr.slice(1,2) == [2]; 通过 slice.call 才能使用call显 ...
- 11 SaltApi
1.APIS https://docs.saltstack.com/en/latest/topics/api.html 1.python client api 必须运行在master节点上 2. 一般 ...
- 宽字符(UNICODE)字符集
推荐使用宽字符(UNICODE)字符集,严格使用宽字符集的函数和定义.具体参考https://blog.csdn.net/qq_22642239/article/details/84822485
- Spring中,请求参数处理
Spring中,Controller里,获取请求数据有多种情况 在使用@RequestParam的方式获取请求中的参数时, 如果没有设置required这个属性,或者主动设置为true,则意味着这个参 ...
- Burpsuite 2.0.11 Beta 破解版下载
1.解包 jar xvf burpsuite_pro_v2.0.11beta.jar 自行定制,删除自带chrome和7zip软件包之后,软件精简至39M. 2.打包 jar cvfm META-IN ...
- BZOJ 1706: [usaco2007 Nov]relays 奶牛接力跑 倍增Floyd
题不难,但是一开始把读入看错了,调了半天qaq~ Code: #include <bits/stdc++.h> #define N 300 #define setIO(s) freopen ...
- DP(第一版)
序 任何一种具有递推或者递归形式的计算过程,都叫做动态规划 如果你一开始学的时候就不会DP,那么你在考试的时候就一定不会想到用动态规划! 需要进行掌握的内容 1)DP中的基本概念 2)状态 3)转移方 ...