Python爬虫实战 | (1) 爬虫基础

目录

 

1. 爬虫概念

2. 网页基础

3. 爬虫常用库

4. 正则表达式

 

1. 爬虫概念

  • 爬虫:是一段自动抓取网页信息的程序
  • 爬虫原理:模拟浏览器打开网页,获取网页中的数据

2. 网页基础

首先可以用Chrome浏览器打开百度首页,查看源代码(Chrome浏览器需要安装谷歌访问助手,不然无法使用,安装详情)。

右键点击"检查"即可打开网页控制台。我们主要关注Elements和Network两个选项卡,Elements里面是当前网页的源码。

  • HTML:超文本标记语言是用来描述网页的一种语言。网页包括文字、按钮、图片和视频等各种复杂的元素,不同类型的元素通过不同类型的标签来表示,他们之间的布局又通过布局标签div嵌套组合而成,各种标签通过不同的排列和嵌套形成了网页的框架。
  • CSS:层叠样式表。"层叠"是指当在HTML中引用了数个样式文件,并且样式发生冲突时,浏览器能依据层叠顺序处理。"样式"指网页中文字大小、颜色、元素间距、排列等格式。
  • JavaScript:一种脚本语言。可以实现实时、动态、交互的页面功能。
  • 总结:HTML定义了网页的内容和结构,CSS描述了网页的布局,JavaScript定义了网页的行为。

HTTP基本原理

URL(Uniform Resource Locator, 统一资源定位符):定义互联网上的唯一资源,一张图片、一个文件、一段视频都可以用URL编码,如:https://www.baidu.com/s?wd=爬虫

一个完整的URL 包括协议部分、网址、文件地址部分。协议部分以//为分隔符,在Internet 中有多种协议:

  • http  —— Hyper Text Transfer Protocol(超文本传输协议)
  • https—— Hyper Text Transfer Protocol over Secure Socket Layer安全套接字层超文本传输协议(http的安全版)
  • ftp  ——   File Transfer Protocol(文件传输协议)

在爬虫中,抓取的页面通常采用http或https协议。

HTTP请求过程

  • 请求(Request):用户将本机信息通过浏览器发送给服务器
  • 响应(Response):服务器接收请求,分析用户发来的请求信息,然后返回数据(返回的数据中可能包含其他链接,如图片,js,css等),浏览器接收Response后解析其内容再显示给用户

爬虫程序模拟浏览器发送请求,然后在接收Response后,提取其中的有用数据。

请求

  • 请求方法(Request Method)

GET:在浏览器中直接输入URL回车

POST:多在表单提交时发起

  • 请求网址(Request URL)
  • 请求头(Request Headers):Cookie、Referer、User-Agent等
  • 请求体(Request Body)

GET请求:请求体没有内容(请求参数放在URL后面,直接能看到,如https://www.baidu.com/s?wd=爬虫)

POST请求:请求内容时格式文本(format data),如登陆窗口、文件上传等信息。

响应

  • 响应状态码(Response Status Code)

200:代表服务器正常响应

404:代表页面未找到

500:代表服务器内部发生错误

  • 响应头(Response Headers):Content-Type、Set-Cookie等
  • 响应体(Response Body):

HTML代码、JSON代码、二进制数据。

爬虫分类

  • 通用爬虫:爬行对象从一些种子URL 扩充到整个Web,主要为门户站点搜索引擎和大型Web 服务提供商采集数据。
  • 聚焦爬虫:选择性地爬行那些与预先定义好的主题相关的页面。

 

robots协议

Robots协议(Robots Exclusion Protocol):网络爬虫排除标准,也称为爬虫协议、机器人协议。Robots协议是国际互联网界通行的道德规范,不是命令,也不是防火墙,并不能阻挡刻意闯入者。网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

例如:https://www.taobao.com/robots.txt,robots.txt是搜索引擎访问网站时要查看的第一个文件。

  • User-Agent:标明针对的客户端类型
  • Allow:标明允许爬取的地址
  • Disallow:标明不希望爬取的地址
  • Sitemap:指导搜索引擎去爬取页面,避免误爬不希望开放的地址。

爬虫流程

3. 爬虫常用库

请求库

  • urllib:Python内置的HTTP请求库
  • requests:第三方请求库,功能强大 ,不能执行JS代码
  • Selenium:驱动浏览器执行JS渲染

解析库

  • lxml:解析和生成xml文件
  • BeautifulSoup:从HTML或XML文件中提取数据
  • PyQuery:相当于jQuery的python实现,可以用于解析HTML网页等。语法和jQuery几乎完全相同

存储库

  • pymysql
  • pymongo
  • redis

其他库

  • re(正则表达式库):通用的网页解析库,也可以对存储后的数据进行数据清洗等相关工作。

4. 正则表达式

正则表达式 (Regular Expression):记录文本规则的代码,常用于检索、替换符合某一规则的文本。

问题:想在一段文本中找寻符合要求的字符串。

思路:根据需要将这些符合要求的特定字符及这些特定字符的组合,形成一个“规则字符串”,通过组合的“规则字符串”来对字符串进行过滤,从而匹配出想要的特定字符串。

正则表达式小抄

贪婪与非贪婪模式

贪婪模式,总是尝试匹配尽可能多的字符。

非贪婪模式,也称为“懒惰”模式,总是匹配尽可能少的字符。

编程语言中正则表达式应用

  • 反斜杠问题

与大多数编程语言相同,正则表达式里使用”\”作为转义字符,这就可能造成反斜杠困扰。

假如需要匹配文本中的字符”\”,那么使用编程语言表示的正则表达式里将需要4个反斜杠”\\\\”:前两个\\和后两个\\分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。

Python里的原生字符串r很好地解决了这个问题,要匹配字符”\”,正则表达式可以用r”\\”来表示。同样,匹配一个数的”\\d”可以写成r”\d”。

Python正则表达式匹配流程

利用正则表达式爬取信息三步曲

  • Step1:先将正则表达式的字符串形式(即规则)编译为正则表达式对象。
prog = re.compile(pattern)
  • Step2:然后使用这一对象处理文本并获得匹配对象,如果匹配不成功,就返回none。
result = prog.match(string)
  • Step3:输出匹配结果。
print(result)

PS:Step1,2可以合并为一步:

result = re.match(pattern, string)

其中pattern可以是正则表达式的字符串形式,也可以是正则表达式对象。

常用正则表达式举例

  • 例1:查找字符串中的数字
string = ‘_234werwrE%58\WeR-wRew'

 

model1 = r'\d'
print(re.findall(model1,string))

model1 = r'\d+'
print(re.findall(model1,string))

  • 例2:查找string中的特殊字符:
model2 = r'[_,$-.%\\]'
print(re.findall(model2,string))

  •  例3:查找string中的指定字符串(忽略大小写)
model3 = r"wer|wre"
print(re.findall(model3,string,re.I))

  • 例4:查找网页中的特定内容
html='<dd><i class="board-index board-index-1">1</i><a href="/films/1203" ' \ 
          'title="霸王别姬"/> <p class="star">主演:张国荣,张丰毅,巩俐</p></dd>'
model4=r'<dd>.*?board-index.*?>(\d+)</i>.*?title="(.*?)"'
             + '.*?star">(.*?)</p></dd>'
print(re.findall(model4,html) , re.S)   

几个好用的正则表达式网站:

  • https://regexper.com --可以用图形来表示正则表达式的效果
  • https://regexr.com/ ----在线测试工具(英文)支持JavaScript
  • http://tool.oschina.net/regex  --在线测试工具(中文)

re库

  • compile()函数

官方文档

re.compile(pattern [,flags=0]):编译一个正则表达式模式,返回一个模式对象。flag是匹配模式,取值如下:

  • match(),search(),findall()函数

re.match(pattern, string, flags=0)  

若string中包含pattern子串,则返回真,否则返回假。注意:只从string的开始位置进行匹配。

re.search(pattern, string, flags=0)  

若string中包含pattern子串,则返回Match对象,否则返回None,注意,会扫描整个string查找匹配,并返回第一个成功的匹配。

re.findall(pattern, string, flags=0)

返回string中所有与pattern相匹配的全部字串,返回形式为数组

reg= re.findall(r'[t,w]h', 'https://docs.python.org/whats')
print (reg)      

  • match()、search()、findall()函数中的方法

  • sub(),split()函数

 re.sub(pattern, repl, string, count=0, flags=0)

输入一个字符串,然后返回被替换后的字符串。

 re.split(pattern, string[, maxsplit])

根据指定子串对string进行分割,结果为列表。

将所有数字替换为空格:

s = ‘54aKS4yrsoiRS4ixSL2g’
content = re . sub(‘\d+’, ’’, s)

用数字进行分隔:

print(re.split('\d+','one1two2three3'))

 

  • 注意事项

  • 常用正则表达式

含义

正则表达式

匹配中文字符

[\u4e00-\u9fa5]

匹配空白行

\n\s*\r

匹配Email地址(无中文)

[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)* @(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?

匹配网址URL

[a-zA-z]+://[^\s]*

匹配国内电话号码

\d{3}-\d{8}|\d{4}-\{7,8}

匹配腾讯QQ号

[1-9][0-9]{4,}

匹配中国邮政编码

[1-9]\d{5}(?!\d)

匹配18位身份证号

^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$

匹配(年-月-日)格式日期(1900-2099年,可匹配闰年)

((((19|20)\d{2})-(0?(1|[3-9])|1[012])-(0?[1-9]|[12]\d|30)) |(((19|20)\d{2})-(0?[13578]|1[02])-31)|(((19|20)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|((((19|20)([13579][26]|[2468][048] |0[48]))|(2000))-0?2-29))$

匹配整数

^-?[1-9]\d*$

import re

emails = ['[email protected]', '1973536%[email protected]', '[email protected]']

pattern = re.compile(r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$')

for email in emails:
    
    if re.match(pattern, email):
        
        print('True')
    
    else:
        
        print('False')

猜你喜欢

转载自blog.csdn.net/sdu_hao/article/details/89310032