整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

绝对干货,Python爬虫处理\xa0、\u3000、\u2002、\u2003等空格

ython爬虫处理\xa0、\u3000、\u2002、\u2003等空格

    • 普通全角空格(\u3000)
    • html实体不间断空格(\xa0)
    • html实体半角空格(\u2002)
    • html实体全角空格(\u2003)

在爬取网页时,对网页数据清洗时常会遇到空格,有的网页空格类型还不止一种,如果不能正确处理,可能无法提取到需要的数据。这里记录下自己使用正则处理各种类型空格的经历。

空格类型

这里把空格格式分两类,一类这里表述为普通文本空格,另一类表述为html实体空格。普通文本空格介绍 普通半角空格普通全角空格 。html实体空格介绍三种,分别为 html实体不间断空格 )、 html实体半角空格 ( )和 html实体全角空格 ( )。

  1. 普通半角空格 :英文空格键。这是最常见的空格,比如我们写代码时,按下空格键产生的就是这种空格键。正则里直接使用空格或者\s就能匹配,在python中对应的unicode码为\u0020;
  2. 普通全角空格 :中文空格键。中文网页上常会出现,直接使用正则的\s匹配不到,unicode码为\u3000;
  3. html实体不间断空格 :html中的常用空格,出现在html中为 。网页上看不到,打开浏览器开发工具可以看到,unicode码为\u00A0,对应的十六进制为\xa0;
  4. html实体半角空格 :&ensp,unicode码为\u2002;
  5. html实体全角空格 :&emsp,unicode码为\u2003;

普通半角空格

这种空格不需要特殊处理,使用正则匹配,可以直接使用空格或者\s。为了以下铺垫,这里也举个用unicode码匹配该类型空格的例子,代码如下所示

s = 'hello word, hi python'
print re.findall(r'i py', s)  # 直接用空格
print re.findall(r'i\spy', s)  # 用\s
print re.findall(ur'i\u0020py', s)  # 用unicode码

执行结果如下

普通全角空格(\u3000)

该链接 导航栏各栏目之间有空格(这个就是\u3000类型的,但是直接看不出来,代码抓取下来可以看到),如下图所示

以下使用代码获取该段文本,并使用正则提取

import re

from requests import get
from lxml import etree

url = 'http://hebng.hljcourt.gov.cn/public/detail.php?id=1818'
headers = {
 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'}
resp = get(url, headers=headers)
html = resp.content.decode('gbk')
et = etree.HTML(html)
text_list = et.xpath('/html/body/table[3]/tr[2]//text()')
text = et.xpath('string(/html/body/table[3]/tr[2])')
print '=' * 50
print re.findall(ur'法院概况 新闻中心', text)  # 匹配不到
print re.findall(ur'法院概况\s新闻中心', text)  # 匹配不到
print re.findall(ur'法院概况\u3000新闻中心', text)  # 这样才可以匹配到
print '=' * 50

执行结果如下

从以上图片可以看到该网页导航栏各栏目之间的空格就是这种\u3000这种空格,这种类型空格要匹配的话需要在正则表达式中使用unicode码。

html实体不间断空格(\xa0)

该链接 正文之间有很多不间断空格,打开开发者工具可以直接看到

以下使用代码获取该段文本,并使用正则提取

import re

from requests import get
from lxml import etree

url = 'http://sthj.tj.gov.cn/ZWGK4828/ZFXXGK8438/FDZDGK27/XZCFQZXZCFXX7581/202010/t20201020_3958760.html'
headers = {
 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'}
resp = get(url, headers=headers)
html = resp.content.decode('utf-8')
et = etree.HTML(html)
text_list = et.xpath('//*[@id="zoom"]/p[30]/text()')
text = et.xpath('string(//*[@id="zoom"]/p[30])')  # 注意申请行政复议前面有四个空格,其中三个不间断空格,一个普通半角空格
print '=' * 200
print re.findall(ur'\s\s申请行政复议', text)  # 普通半角接普通半角匹配不到
print re.findall(ur'\xa0\s申请行政复议', text)  # 不间断空格接普通半角空格可以匹配到
print re.findall(ur'\u00A0\s申请行政复议', text)  # 不间断空格接普通半角空格可以匹配到
print '=' * 200

执行结果如下

从以上图片结果可以看出,使用正则匹配非间断空格时,需要使用unicode码\u00A0或者十六进制\xa0。

html实体半角空格(\u2002)

该链接 正文末尾的日期前面有很多**&ensp**这种空格,打开开发者工具可以直接看到

以下使用代码获取该段文本,并使用正则提取

import re

from requests import get
from lxml import etree

url = 'http://sthj.tj.gov.cn/ZWGK4828/ZFXXGK8438/FDZDGK27/XZCFQZXZCFXX7581/202112/t20211207_5743296.html'
headers = {
 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'}
resp = get(url, headers=headers)
html = resp.content.decode('utf-8')
et = etree.HTML(html)
text_list = et.xpath('//*[@id="zoom"]/div/p[38]/span[1]/text()')
text = et.xpath('string(//*[@id="zoom"]/div/p[38]/span[1])')
print '=' * 200
print re.findall(ur'\s20', text)  # 普通半角匹配不到
print re.findall(ur'\u200220', text)  # unicode码\u2002可以匹配到
print '=' * 200

执行结果如下

从以上图片结果可以看出,使用正则匹配html实体半角空格时,需要使用unicode码\u2002。

html实体全角空格(\u2003)

该链接 正文表格表头有一列中有该类型空格, ,如下图所示

以下使用代码获取该段文本,并使用正则提取

import re

from requests import get
from lxml import etree

url = 'http://hebng.hljcourt.gov.cn/public/detail.php?id=1818'
headers = {
 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'}
resp = get(url, headers=headers)
html = resp.content.decode('gbk')
et = etree.HTML(html)
text_list = et.xpath('//table[@class="ke-zeroborder"]/tbody/tr[1]/td[1]/text()')
text = et.xpath('string(table[@class="ke-zeroborder"]/tbody/tr[1]/td[1])')
print '=' * 200
print re.findall(ur'\t\s\r', text_list[0])  # 普通半角匹配不到
print re.findall(ur'\t\u2003\r', text_list[0], flags=re.S)  # unicode码\u2003可以匹配到
print '=' * 200

执行结果如下

从以上结果看出,使用正则匹配html实体半角空格时,需要使用unicode码\u2003。

统一处理方式

从以上几个例子可以看出,网页上的空格类型要想处理好,是要兼顾几种情况的,其实爬虫主要遇到的就是\xa0、\u3000这两种。可以使用统一正则匹配,如下测试代码

import re

s = u'\u2002\u2003\xa0\u3000Say'

print len(s)
print s
print re.findall(r'\s{4}Say', s)  # 普通空格匹配不到
print re.findall(ur'[\u2002\u2003\xa0\u3000]{4}Say', s)  # 使用unicode码可以匹配到
print re.findall(r'\s{4}Say', s, flags=re.U)  # 使用re.U模式可以匹配到

代码执行结果如下

注意看以上结果,这里的s是unicode字符串,共7个字符,其中四个不同类型的空格,使用对应的unicode码可以匹配到这些空格。

要注意下当正则模式的编译标志位(flags)为re.U时,使用正则符号\s是可以匹配到各种类型的空格的

最后安利一个查unicode字符的网站unicode-table,可以在 html实体 这里看到有许多html中不同类型的空格。

:为什么SEO人员要学会HTML代码标签的使用?

请注意,会建站不一定意味着懂HTML,现在随便找个CMS或者博客程序(如WordPress、Z-blog),一个毫无HTML常识的菜鸟都能轻易建站,所以我要强调“一定要懂HTML”。或许很多人在网上看到或者听某家SEO培训机构说:“SEO很简单,你在我们这里学会了,以后直接去指导别人就可以,所以学SEO不用懂HTML”,不要以为我危言耸听,我确实碰到过很多朋友走进了这样的误区,在这里我想说:“学SEO不懂HTML,那你就不用学了!” HTML是SEO不可或缺的一部分,关键词布局、策略的调整都离不开HTML,网站制作时的诸多修改、调整也要用到HTML,想学SEO,先学会HTML吧!


① 首先我们大体来介绍了网页的基本结构,网页里面标签分为head和body标签,翻译起来很容易理解。head是头部,里面包含着title(网页标题)、keyword(关键词)、description(网页描述)这三个基本标签,可能还有css以及JS等在head标签里面,这里我们先不用管他。而我们一般SEOer主要工作就是做网页标题、关键词、描述这几个块,这是不得不做的,但是主要内容都还在body里面,其实这个我们可以把它理解为身体,一个比较成熟的网页要求五脏六腑俱全。所以里面有很多模块和功能,现在比较流行的CSS+DIV,代码比较简洁,美观,表现力比较强,所以table也渐渐的退出市场,因为对SEO来说table(表格)占用内存比较多,是DIV的10倍以上,所以我们也能不用最好不用。

② 做SEO还必须知道代码的规范标准,现在通过W3C标准很难,因为网站很难不出现错误,其实细小的错误肯本没有影响,只要不多搜索引擎也比较容易接受。但是能不错误就不要出现,网页前面最好申明标准体系,一般我们中国大陆的编码是GB2312和UTF-8,一般后者用的比较多,这个我们先不解释。

③ 还有就是现在搜索引擎可以读懂JS代码,所以对网站影响越来越小,不要在影响用户体验的情况下而去除JS,这是不明智的。特别是谷歌,几年前就可以读懂一般性JS代码,就算是导航也没有影响,但是这里我们也不推荐用JS写导航.如果朋友们现在想学Html知识了,我向大家推荐去下本HTML标签的电子书,里面的例子很多,也很详细,非常适合初学者。如果你想成为一名合格的优化,那么就去学下HTML,不然程序员会认为你什么都不懂在瞎指挥。


SEO人员应该都知道HTML语言是什么?那么我就来给大家写一篇SEO和HTML的文章,所以本文就为广大的seo人员介绍SEO必须懂的HTML代码标签。总体来说,SEO人员大部分情况下并不需要直接参与网站程序的编写,所以,我们只需要能看懂一部分html代码,并且在工具的辅助下,能够增、改、删这9个标签就可以了。


二:SEO人员必须懂的HTML语言代码

1.标题标签:如果我们不知道网页的标题是由哪个标签来控制的,是一件很失败的事情。曾与一位朋友交流其站点的优化问题,我对他说页面的标题要优化一下,标题的写法最好是“文章标题-栏目名称-网站名称”的结构,结果他将正文的标题修改了。这充分说明这位朋友并 懂标题标签,所以不知道如何去修改页面标题。而页面标题对于搜索引擎来说是非常重要的,所以我们 作为SEO人员,一定要会使用标题标签。


2.页面关键词标签:作为SEO人员,所有的工作内容都是在做与关键词相关的工作,所以我们千万不能将这个标签忽略了。对于常见有两种错误:

a. 没有使用页面关键词标签:通过源码,我们可以发现很多网站其实没有这个标签。没有此标签的网站,大部分情况是因为CMS程序不支持,而有些则是因为不明 白它的作用,所以没有添加。不论是那种情况,我们都可以通过某些方法来改进。
b. 关键词分隔符号使用不正确:关键词内容的正确形式是【content=“关键词,关键词2,……”】,关键词与关键词之间使用英文半角逗号分隔开来,而不是使用下划线、竖线或者空格等符号。


3.页面描述标签:此标签可以看着是定义文章的主要内容,与标题一样,搜索引擎会将其显示在搜索结果页中。所以我们千万不要忽略,甚至于我们可以利用这一点来将一些促销和利好信息展示给搜索者,描述的写法可以参见我们之前的文章。


4.默认地址标签:在某些情况下,我们的网站会被某些人恶意复制,造成网站排名下降和权重流失等损失,为了在一定程度上防御这种复制带来的后果,很 多SEO人员提出在外链接中使用绝对url的方法。实际上除了使用绝对地址,我们还可以使用默认地址标签,使用了默认地址标签的页面,其页内所有的相对url地址所指定的url作为基准,进行链接。同时,在此也提醒一下建站的朋友,如果使用了默认地址标签,在修改各种包含文件--如css,js等引用文件--的时候,要去掉默认地址标签,否则修改本地文件是无效的,因为它会默认去调用href指定的文件。


5.文字加粗标签:这两组html标签在 视觉效果上都是让文字加粗,都有强调的作用,它会告诉用户和搜索引擎,这部分内容在本页面是很重要的。所以我们在页面中可以将重要的词组--一般是关键 词,进行或加粗强调。但是要避免通篇都是加粗,或者 通篇都没有词组被加粗,这两种方式都是不可取的。大部分情况下,使用或者效果是类似的,有专家 提出使用字符更少、更能节约带宽,所以建议将都换 成,但显然这个理由并不是那么充分和吸引人,几个字符,对于现在的福鼎网络速度来说,完全可以忽略不计。


6.内容最大标题标签:被包含的内容,搜索引擎会给予很高的权重,所以作为SEO人员,一定要重视这一点。并且要记住:是用来定义正文内容最大标题,而不是页面标题,不要与混淆。同时,一个页面只允许有一个标签,否则会被认为是作弊--目前来说是这样的,HTML5拥有更强的功 能,允许一个页面有多个标签,但目前还未完全被搜索引擎所支持,所以我们坚持在一个页面使用一个是没错的。


7.内容次级标题标签:一篇文章,除了标题,还会有各种次级段落标题,比如本文:就存在多个次级标题。一般建议,页面必须有和标签,和标签不作要求,也不建议使用及更次级的标签,因为作用不大,但 不阻止使用,因为他们是文档的标准标签,即使无用,也无害。


8.超链接标签:作为SEO人员,这个HTML标签是必须懂的,在互联网中超链接标签可以说是灵魂一般的存在,如果 没有超链接标签,网站将失去意义。不管我们是做锚文本,还是做图片链接,都需要使用它。这里我们要注意它的两个属性,一个是【target】,它决定了链接以何种方式打开,一般站内链接会被定义为在当前页面打开,外部链接被定义为在新窗口中打开。另外一个属性是【rel】,其最让SEO人员关注的就是【Nofollow】值,因为它代表不传递权重。对内可以集中权重,不使其分散到无意义的页面;对外,可以防止权重流失和避免被骗友情链接。


9.图片标签:图片标签我们要注意的是其【alt】属性,因为搜索引擎并不认识图片,而【alt】属性则在大概意义上告诉了搜索引擎此图片的内容。 所以,作为SEO人员,一定要重视【alt】属性的使用,对每一幅具有实际意义的图片都应该加上【alt】属性,并为其指定内容。在大多数浏览器中,定义 了【alt】属性内容的图片,当鼠标悬停在图片上的时候,会显示【alt】属性值:鼠标悬停显示【alt】属性值


另外两个属性【widht】和【height】用来定义图片的宽度和高度,大部分情况下,很多程序编写人员都是忽略,让浏览器自行判断图片的大小。 这种做法在图片的显示上面是没有什么错误的,但是忽略【width】和【height】属性,会增加图片显示的时间,所以我们应该主动给图片加上宽度和高 度属性,并指定其值。


关注本头条(常州姜东),带您详细了解SEO培训优化十四步:(如何做出一个好的SEO效果)


1、做SEO优化第0步:你真的了解SEO优化吗?浅谈网站优化之用户体验优化

2、做SEO优化第一步:初步了解SEO的作用

3、做SEO优化第二步:背熟所有SEO基础名词

4、做SEO优化第三步:学习了解HTML基础知识
5、做SEO优化第四步:学会搭建一个个人网站(cms系统)

6、做SEO优化第五步:定位目标关键词和长尾关键词
7、做SEO优化第六步:设置Title、keywords和Description

8、做SEO优化第七步:如何选择网站程序模版?

9、做SEO优化第八步:如何设置网站目录优化?
10、做SEO优化第九步:如何设置页面内容优化

11、做SEO优化第十步:内容源找寻和网站更新维护方法
12、做SEO优化第十一步:如何设置外部链接优化

13、做SEO优化第十二步:网站优化推广方案
14、做SEO优化第十三步:一定要最好用户体验优化


业图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        h1{
            text-shadow: 5px 5px 5px #FF0000
        }
    </style>
</head>
<body>
    <h1>王耶浪Web开发学习笔记</h1>
</body>
</html>

(1)word-wrap 用来强制换行。

其语法格式为:

word-wrap: normal|break-word;

属性值说明:

  • normal:只在允许的断字点换行(浏览器保持默认处理)。
  • break-word:在长单词或 URL 地址内部进行换行。

例子,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            width:300px;
            border: 1px solid rgb(179, 126, 223);
            word-wrap: break-word;
        }
    </style>
</head>
<body>
    <div>
        “The bad news is time flies. The good news is you're the pilot.” - Michael Altshuler
    </div>
</body>
</html>

(2)word-break 属性也是用来强制换行的。

其语法为:

word-break: normal|break-all|keep-all;

取值说明:

描述

normal

使用浏览器默认的换行规则。

break-all

允许在单词内换行。

keep-all

只能在半角空格或连字符处换行。

例子,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            margin-top: 40px;
        }
        #text1{
            border: 1px solid rgb(179, 126, 223);
            width:100px;
            word-break: break-all;
        }
        #text2{
            border: 1px solid rgb(179, 126, 223);
            width:100px;
            word-break: keep-all;
        }
    </style>
</head>
<body>
    <div id="text1">
        “The bad news is time flies. The good news is you're the pilot.” - Michael Altshuler
    </div>
    <div id="text2">
        “The bad news is time flies. The good news is you're the pilot.” - Michael Altshuler
    </div>
</body>
</html>

(3)练习:挑战一下,word-break

在前面的内容中,我们已经学习过关于 word-break 属性的使用了。这里我们来挑战一下自己吧!

知识点

  • word-break 属性

挑战准备

创建一个html 文件,并写入如下所示 HTML 页面框架。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
</html>

实验要求

  1. 新建一个 html 文件。
  2. 页面上有两对同级的 p 标签,分别添加类选择器为:test1test2
  3. 设置 test1 的样式为:宽为 9em,边框的粗细为 1px,边框颜色为黑色,背景颜色为 aquamarine,只能在半角空格或连字符处换行。
  4. 设置 test2 的样式为:宽为 9em,边框的粗细为 1px,边框颜色为黑色,背景颜色为 darkgreen,允许在单词内换行。

验证测试

按以上要求用 HTML 完成以下效果: