python 爬虫入门该怎么学习?

news2024/11/14 17:50:07

前言

1、什么是爬虫和爬虫的基本逻辑

“爬虫”是一种形象的说法。互联网比喻成一张大网,爬虫是一个程序或脚本在这种大网上爬走。碰到虫子(资源),若是所需的资源就获取或下载下来。这个资源通常是网页、文件等等。可以通过该资源里面的url链接,顺藤摸瓜继续爬取这些链接的资源。

你也可以把爬虫当作模拟我们正常上网。打开网页并分析网页的内容获取我们想要的东西。

那么,这里就涉及到http传输协议等相关的知识。

我们通常打开一个网页,基本上都是打开一个Url链接即可。在这个过程当中,实际上发生了很多事情。

打开一个Url链接,浏览器自动向Url链接的服务器发送一个请求(Request),告诉服务器说我需要访问这个Url链接的内容,请返回数据给我。服务器就处理该请求,响应该请求并返回结果给浏览器。

既然爬虫需要模拟该过程。根据http协议,爬虫需要构造一个请求(Request),发到请求到目标服务器(通常是Url链接)。然后等待服务器的响应(Response)。

所有相关的数据都在这个响应结果当中,这个就是爬虫实现的基本逻辑。

2、urllib2实现GET请求

GET和POST是请求中最常见的两种方式。(一共有6种)

GET方式是通过Url链接的方式传输相关的参数或数据。一般打开网址是GET方式请求,例如打开百度首页、谷歌首页。

有时候,需要向这个链接传输一些参数。

例如我在百度搜索一个词,发现链接变成 https://www.baidu.com/s?ie=UTF-8&wd=测试

这里有个?问号以及后面一堆数据。问号后面的数据是GET请求的参数,这里一共有两组参数。

1)ie = UTF-8

2)wd = 测试

每组参数用&符号链接。在参数中,等号前面的是参数名;等号后面的是参数值。

例如第2组参数的含义是百度搜索关键字为“测试”。第1组参数是设置返回ie浏览器的编码格式,可有可无,作为说明加入进来。

那么,我使用urllib2模拟百度搜索代码如下:

#coding:utf-8
import urllib, urllib2
 
#前半部分的链接(注意是http,不是https)
url_pre = 'http://www.baidu.com/s'
 
#GET参数
params = {}
params['wd'] = u'测试'.encode('utf-8')
url_params = urllib.urlencode(params)
 
#GET请求完整链接
url = '%s?%s' % (url_pre, url_params)
 
#打开链接,获取响应
response = urllib2.urlopen(url)
 
#获取响应的html
html = response.read()
 
#将html保存到文件
with open('test.txt', 'w') as f:
    f.write(html)

执行代码,可以看到爬取的内容。

在这里插入图片描述
在这里插入图片描述
上面的链接之所以是http,不是https。因为百度在https做了重定向,重定向到http的链接。

若直接获取https的链接内容是获取不到什么数据。

另外,后面我们会讲解如何处理html的内容,怎么从html中获取我们所需的数据。

好了,先讲解一下代码。

在合并Url链接的时候,使用了urllib库的urlencode方法。该方法是将字典组成x1=a&x2=b的形式。

再看第9行代码,我使用encode方法是为了处理unicode字符串为string字符串。若不做该处理,urlencode方法无法使用。

以上这些都是一些不得不讲的细节,整段代码的核心是第16行和第19行。

第16行是使用urlopen方法打开一个Url链接,发送请求并等待响应;

第19行是从响应(Response)中获取网页的html代码即网页内容。

urlopen方法还有其他参数,格式如下:

urllib2.urlopen(url, data, timeout)

后面两个参数是选填的,data参数是接下来要讲的POST请求所使用到的参数;timeout参数是设置超时时间。

为了避免过长时间未响应,可以使用timeout设置。

urlopen方法还有另外一种格式:

urllib2.urlopen(request, data, timeout)

我比较倾向使用这个方式,逻辑清晰,而且还可以对request做其他设置。上面百度搜索代码可以改成如下:

#coding:utf-8
import urllib, urllib2
 
#前半部分的链接(注意是http,不是https)
url_pre = 'http://www.baidu.com/s'
 
#GET参数
params = {}
params['wd'] = u'测试'.encode('utf-8')
url_params = urllib.urlencode(params)
 
#GET请求完整链接
url = '%s?%s' % (url_pre, url_params)
 
#构造请求,获取响应
request = urllib2.Request(url)
response = urllib2.urlopen(request)
 
#获取响应的html
html = response.read()
 
with open('test.txt', 'w') as f:
    f.write(html)

3、urllib2实现POST请求

POST请求通常是Form表单提交数据常用的请求方式。

相对GET请求来说,POST请求可以向服务器传递更多的数据。这点是它们之间主要的区别。

通常出现在登录、提交表单、向API接口发送JSON数据这几种情况。

这里需要借助一些辅助工具帮助我们查看浏览器和服务器之间的小动作。

例如在浏览器按F12调试或Fiddler,这些又是一大块知识。大家可以自行搜索和学习。

有关POST请求代码和GET请求差不多。这里没有较好的简单实例,因为很多网址对POST先加密再发送或者加了验证码等等处理。

简单写个表单提交的POST请求代码示例代码,了解一下:

#coding:utf-8
import urllib, urllib2
 
#构造表单数据,表单数据也是和GET请求一样的形式
values = {}
values['username'] = "aaaaaa"
values['password'] = "bbbbbb"
data = urllib.urlencode(values)
 
#构造请求
url = "http://xxxxxxxxxxx"
request = urllib2.Request(url, data)
 
#响应结果
response = urllib2.urlopen(request)
html = response.read()
print(html)

4、urllib2处理Cookie

http协议还有一个特性:无状态。

因为http协议是处理请求并响应结果,服务器并不知道客户端处于什么状态。例如客户端是否已经登录、客户端访问该Url链接之前打开了什么网页等等。面对这种情况,Cookie就诞生了。

Cookie记录了一些简单的数据。而每个Cookie都有有效期。我们可以标记该客户端当前的状态,例如是否登录、之前查询过什么东西、打开过该网站什么网页等等。

(ps:Cookie是保存在客户端,服务端还有一个差不多的东西:Session,可自行了解。)

urllib2可以获取和记录Cookie。这里需要构造一个opener,不是使用urllib2.urlopen。

urllib2.urlopen也是一个特殊的opener,但我们无法从中获取Cookie。如下代码:

#coding:utf-8
import urllib2
import cookielib
 
#创建cookie
cookie = cookielib.CookieJar()
handler=urllib2.HTTPCookieProcessor(cookie)
 
#通过handler来构建自定义opener
opener = urllib2.build_opener(handler)
 
#此处的open方法同urllib2的urlopen方法
request = urllib2.Request('http://www.baidu.com')
response = opener.open(request)
for item in cookie:
    print('%s = %s' % (item.name, item.value))

自定义一个opener,获取Cookie如下:
在这里插入图片描述
我们还可以将Cookie保存到文件,下次需要使用的时候,再读取出来。让服务器误以为我们还在之前的某种状态。

#coding:utf-8
import urllib2
import cookielib
 
#设置保存cookie的文件路径
filename = 'cookie.txt'
 
#使用MozillaCookieJar创建cookie对象
cookie = cookielib.MozillaCookieJar(filename)
handler = urllib2.HTTPCookieProcessor(cookie)
 
#通过handler来构建opener
opener = urllib2.build_opener(handler)
 
#创建请求,同urllib2的urlopen
response = opener.open("http://www.baidu.com")
cookie.save(ignore_discard=True, ignore_expires=True)

其中,save方法的参数含义如下:

1)ignore_discard是即使cookies将被丢弃,也将其保存下来。

2)ignore_expires是如果在该文件中cookies已经存在,则覆盖写入。

读取Cookie代码如下:

#coding:utf-8
import urllib2
import cookielib
 
#使用MozillaCookieJar创建cookie对象
cookie = cookielib.MozillaCookieJar()
cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
handler = urllib2.HTTPCookieProcessor(cookie)
 
#通过handler来构建opener
opener = urllib2.build_opener(handler)
 
#创建请求,同urllib2的urlopen
request = urllib2.Request("http://www.baidu.com")
response = opener.open(request)

5、反爬虫设置header

有些服务器为了避免被爬虫,会检查header。header是发送请求的时候,一起发送给服务器的数据。可以通过header得到浏览器的类型,手机端还是电脑端访问,以及从什么地方进入该链接等等。

若发现不是正常浏览器访问,服务器则直接拒绝。

so~ 我们需要进一步模拟浏览器的行为,需要模拟设置header。

#coding:utf-8
import urllib, urllib2  
 
#设置header
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'  
headers = {'User-Agent':user_agent} 
 
#构造Request请求,其中第二个参数是data
url = 'http://www.server.com/login'
request = urllib2.Request(url, None, headers)
 
#响应请求
response = urllib2.urlopen(request)  
html = response.read()

同样,若你不知道如何设置header,可以通过抓包软件获取,例如Fiddler。

6、解析html

前面说了这么多,都是为了获取网页内容html。既然获取到html之后,我们解析?从中提取我们需要的数据?

我们所获取的html本质是字符串。处理字符串最基本的方法是通过相关的字符串函数,但效率很低,容易出错。

还可以使用正则表达式处理字符串。这部分的知识也是很多,大家可以自行了解。

这里,我想给大家说的处理方式是使用BeautifulSoup。

BeautifulSoup是解析html/xml的库。非Python自带的库,安装如下:

pip install beautifulsoup4
pip install lxml

安装lxml库是为了加快html解析效率。

先我们设置1个html内容,使用BeautifulSoup解析方法如下:

#coding:utf-8
from bs4 import BeautifulSoup
 
#先随便假设一个html
html = '''<html>
<head></head>
<body>
    <p id="test_p" class="test">test1</p>
    <p class="test">test2</p>
</body>
<html>'''
 
#使用lxml解析html
soup = BeautifulSoup(html, 'lxml')

soup是解析得到的解析器。我们可以根据html的结构获取对应的节点。例如我想获取p标签:

p = soup.body.p

但该方法只能获取到第1个节点。假如body标签下有很多p节点,该方法无法获取全部。

这里,我们可以用find_all或select方法获取。建议大家使用select方法,这个方法可以jQuery选择器用法差不多。例如:

p1 = soup.select('p') #获取p标签
p2 = soup.select('#test_p') #获取id为test_p的标签
p3 = soup.select('.test')   #获取class为test的标签
p4 = soup.select('body .test') #获取body下的class为test的标签

来个完整的代码,输出结果:

#coding:utf-8
from bs4 import BeautifulSoup
 
#先随便假设一个html
html = '''<html>
<head></head>
<body>
    <p id="test_p" class="test">test1</p>
    <p class="test">test2</p>
</body>
<html>'''
 
#使用lxml解析html
soup = BeautifulSoup(html, 'lxml')
 
#获取全部p标签
for p in soup.select('p'):
    print(p)

通过该方法,可以输出全部p标签。

那假如我要获取p标签的属性和数据呢?方法如下:

for p in soup.select('p'):
    print(p.name) #标签名称
    
    #标签属性,也可以用p['id']。若属性不存在会报错,和字典获取键值类似
    print(p.get('id')) 
    print(p.string) #标签内容

若一个标签里面有很多子标签,你可以再进一步继续使用select。

若想获取标签下全部子标签的文本内容。可以用strings属性得到一个生成器,不过可能有很多回车和空格。若想屏蔽回车和空格,可以使用stripped_strings属性。如下所示:

print(''.join(soup.body.strings))
print(''.join(soup.body.stripped_strings))

将分别得到:

u'\ntest1\ntest2\n'
u'test1test2'

7、综合实例

讲了这么多,来个实例:获取百度搜索结果。

输入关键词,爬取百度搜索第1页的结果。我们可以先随便搜索一个词,看看html有什么特征。

在这里插入图片描述
发现搜索的到内容都在class为t的标签下,分别可以获取到文本内容和链接。完整代码如下:

#coding:utf-8
import urllib, urllib2
from bs4 import BeautifulSoup
import codecs
 
def get_contents(word):
    #前半部分的链接(注意是http,不是https)
    url_pre = 'http://www.baidu.com/s'
 
    #GET参数
    params = {}
    params['pn'] = 20 #设置这个每页可以获取10个内容
 
    #若是unicode编码,转成str
    if isinstance(word, unicode):
        params['wd'] = word.encode('utf-8')
    url_params = urllib.urlencode(params)
 
    #GET请求完整链接
    url = '%s?%s' % (url_pre, url_params)
 
    #打开链接,获取响应
    request = urllib2.Request(url)
    response = urllib2.urlopen(request)
 
    #获取响应的html
    html = response.read()
 
    #解析内容
    soup = BeautifulSoup(html, 'lxml')
    items = soup.select('.t a')
    
    #写入文件
    f = codecs.open('test.txt', 'w', 'utf-8')
    for item in items:
        f.write('%s\r\n' % ''.join(item.stripped_strings))
        f.write('%s\r\n\r\n' % item['href'])
    f.close()
 
if __name__ == '__main__':
    get_contents(u'测试')

运行得到结果如下:

在这里插入图片描述

这里我还使用了codecs模块,保存utf-8格式的文本文件。

总结了一些Python学习笔记,大家可以在文末名片自取哈~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/69360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android NDK 开发之 CMake 必知必会

Android Studio 从 2.2 版本起开始支持 CMake ,可以通过 CMake 和 NDK 将 C/C 代码编译成底层的库&#xff0c;然后再配合 Gradle 的编译将库打包到 APK 中。 这意味就不需要再编写 .mk 文件来编译 so 动态库了。 CMake 是一个跨平台构建系统&#xff0c;在 Android Studio 引…

12月7日 补充数据库链式操作,只生成sql语句,不执行sql的几种函数以及thinkphp中验证器

补充知识&#xff1a; 生成sql语句但是不会执行sql语句 public function fetchSqlTest(){$result Db::name(user)->fetchSql(true)->select();//dump($result);//使用正常select查询默认中select(true&#xff09;改为false即可返回sql语句$result Db::name(user)->…

UNIX/LINUX操作系统内核结构

通用操作系统的现状和分类 UNIX操作系统的根本特点&#xff1a;分时多用户、开放性 基本功能特征 系统结构 操作系统核心 系统调用的集合及实现系统调用的内部算法就形成操作系统核心 系统调用 以函数形式提供给核外的命令和上层应用系统使用的一组程序&#xff0c;涵…

观察者模式

目录 一、观察者模式解决了哪些问题&#xff1a; 二、体检的小栗子 三、什么是观察者模式 四、代码实现 一、观察者模式解决了哪些问题&#xff1a; 对象之间的一对多依赖关系应该在不使对象紧密耦合的情况下定义。应该确保当一个对象改变状态时&#xff0c;自动更新无限数…

5-5:显示系统的通知

通知列表 显示评论、点赞、关注三种类型的通知。 通知详情 分页显示某一类主题所包含的通知。 未读消息 在页面头部显示所有的未读消息数量 通知存在message表里面 修改MessageMapper.java package com.nowcoder.community.dao;import com.nowcoder.community.entity.Messa…

毕业2年,跳槽到我们公司拿18K,这就是00后卷王带来的压迫感吗?

内卷&#xff0c;是现在热度非常高的一个词汇&#xff0c;随着热度不断攀升&#xff0c;隐隐到了“万物皆可卷”的程度。 在程序员职场上&#xff0c;什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事&#xff0c;我们可以帮他。 是技术太强的人吗?也不…

AI 也会写代码了,但我并不担心

如果你比较关注人工智能&#xff0c;可能会注意到最近圈子的人都在刷屏一个 AI 玩意&#xff0c;叫 ChatGPT 。我一直关注的和菜头在他的公众号槽边往事上就接连写了几篇文章。为什么和菜头是男的&#xff0c;读者却要叫他“婶婶”怎么把AI逼到生气水文与干货如果看完上面的第一…

一行代码 网页变灰

背景 想必大家都感受到了&#xff0c;很多网站、APP 在昨天都变灰了。 先来感受一下变灰后的效果。 让网页变为黑白配色&#xff0c;是个常见的诉求。而且往往是突如其来的诉求&#xff0c;是无法预知的。 当发生这样的需求时&#xff0c;我们需要迅速完成变更发布。 这种…

机器学习 决策树 随机森林

文章目录参考决策树指标基尼系数基础公式公式理解引入划分后的公式划分后公式的理解信息熵、信息增益如何理解信息熵两种指标的对比总结参考 b站视频 【决策树、随机森林】附源码&#xff01;&#xff01;超级简单&#xff0c;同济大佬手把手带你学决策树决策树模型及案例&…

收藏 外贸企业必备的跨境电商B2B出口报关完整指南

跨境企业想要将货物出口到国外&#xff0c;报关是重要步骤之一&#xff0c;它是货物合法进出国境的通行证。许多初入跨境电商行业的B2B企业在报关上由于无人指引走了许多弯路&#xff0c;浪费了时间。 一.跨境出口模式 根据海关总署规定&#xff0c;跨境电商出口的监管模式分为…

QDataStream(数据流)

QDataStream类实现将QIODevice的二进制数据串行化。一个数据流就是一个二进制编码信息流&#xff0c;独立于主机的操作系统&#xff0c;CPU或字节顺序。QDataStream可以实现c的基本数据类型的串行化。 构造函数&#xff1a; 常用函数 &#xff1a; atEnd()是否到达结束位置re…

基于jsp+ssm的旅游活动报名系统-计算机毕业设计

项目介绍 本系统主要采JSP语言进行编写&#xff0c;本系统数据库采用数据处理功能强大的MySQL来建立 管理员可以通过结伴休闲平台进行旅行社管理、个人活动管理、旅行社活动管理、客户管理、用户管理等。个人用户则可通过结伴休闲平台对进行发布活动、结伴活动等。旅行社用户…

STC15 - ExternalRAM_enable()/InternalRAM_enable()

文章目录STC15 - ExternalRAM_enable()/InternalRAM_enable()概述实验环境MCU的规格区别IAP15F2K61S2的使用限制实验的组合公用测试代码1. 没有焊接外部RAM ExternalRAM_enable()2. 没有焊接外部RAM InternalRAM_enable()3. 焊接外部RAM ExternalRAM_enable()4. 焊接外部RAM…

世界杯狂欢季,家居品牌仅靠4位UP增长2000wB站声量

时隔四年&#xff0c;2022年卡塔尔世界杯于11月21日正式开始&#xff0c;直至目前比赛进度已过半程&#xff0c;这场世界赛事备受各国瞩目&#xff0c;全网有关于“足球”的运动信息接踵而至。 飞瓜数据&#xff08;B站版&#xff09;显示&#xff0c;B站平台带有“世界杯”标…

React源码之概念篇

React主要的三部分 这是从ReactDom.render后触发的步骤 调度协调渲染 设计理念 首先在React中需要在浏览器刷新一次就需要执行如下的步骤&#xff1a; JS脚本执行->样式布局->样式绘制&#xff0c;如果js执行时间超过了16.6ms&#xff0c;那么就没有时间留给样式布局…

[附源码]计算机毕业设计良辰之境影视评鉴系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【viper】go 配置管理神器viper使用详解

目录一、viper简介二、基本使用1.viper基本配置2.读取配置3.自定义配置源4.注册别名4.获取环境变量5.获取命令行参数6.多实例使用7.监听配置变化三、读取远程配置四、保存配置一、viper简介 viper是一个应用程序解决方案&#xff0c;它支持在应用程序内使用&#xff0c;特性如…

基于元胞自动机的人员疏散模拟器研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

[前端面试题]:数组去重的几种方法

总结一些日常需要用到的一些api&#xff0c;也是在一些面试中会经常出现的题目&#xff0c;今天分享的是数组去重的几个不同的方法&#xff0c; 同时文章也被收录到我的《JS基础》专栏中&#xff0c;欢迎大家点击收藏加关注。 给大家推荐一个实用面试题库 1、前端面试题库 &am…

魔兽世界开服架设教程—魔兽国服停服时间已确定!玩家该何去何从

《魔兽世界》国服停止运营时间定在&#xff0c;2023年1月24日0点起 近期随着暴雪和网易公司先后发出的公告&#xff0c;《魔兽世界》国服关服时间已经十分确定了&#xff0c;国服停运时间定在明年的1月24号0点起正式关服。随着国服将关闭&#xff0c;魔兽私服即将崛起。毕竟在游…