adinxu
by adinxu
1 分钟 阅读用时

分类

标签

python爬取网页

文章目录

html网页

<link> 标签定义文档与外部资源的关系。
rel 属性规定当前文档与被链接文档之间的关系。
rel=”canonical”属性值 告诉搜索引擎当前网站中的重复或相似的网页中,哪一个页面才是站长想让其抓取与收录的。

meat

<meat> 提供了 HTML 文档的元数据。元数据不会显示在客户端,但是会被浏览器解析。

script及style

head里面基本就是link还有meat,其他就还有js的<script>以及css的<style>了。

body

div

<div> 是一个块级元素。这意味着它的内容自动地开始一个新行。实际上,换行是

main

<main> 元素中的内容对于文档来说应当是唯一的。它不应包含在文档中重复出现的内容,比如侧栏、导航栏、版权信息、站点标志或搜索表单。
注释:在一个文档中,不能出现一个以上的 <main> 元素。<main> 元素不能是以下元素的后代:<article>、<aside>、<footer>、<header> 或 <nav>。

无用的元素

svg

SVG 意为可缩放矢量图形,使用 XML 格式定义图像。

ul

定义无序 HTML 列表。在csdn中,目前发现用于标题和代码块前的序号。

hljs-button属性

按钮样式

class

类名,用于应用css样式

name

name 属性用于指定锚(anchor)的名称。

id

id 属性规定 HTML 元素的唯一的 id。id 在 HTML 文档中必须是唯一的。id 属性可用作链接锚(link anchor),通过 JavaScript(HTML DOM)或通过 CSS 为带有指定 id 的元素改变或添加样式。id 属性看作是 name 属性的升级版本。

onclick

当点击按钮时执行一段 JavaScript。

rel

rel 属性指示被链接的文档是一个样式表。

img

定义 HTML 页面中的图像

hr

在 HTML 页面中创建一条水平线

br

在文档中插入换行符。

beautifulsoap

Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。

使用

将一段文档传入BeautifulSoup 的构造方法,就能得到一个文档的对象, 可以传入一段字符串或一个文件句柄.

from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("&lt;html&gt;data&lt;/html&gt;")

Beautiful Soup会选择最合适的解析器来解析这段文档,如果手动指定解析器那么Beautiful Soup会选择指定的解析器来解析文档.

四大对象种类

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

Tag

tag通俗点讲就是 HTML 中的一个个标签。可以利用 soup加标签名轻松地获取这些标签的内容,它查找的是在所有内容中的第一个符合要求的标签。

print soup.a
#&lt;a class="sister" href="http://example.com/elsie" id="link1"&gt;&lt;!-- Elsie --&gt;&lt;/a&gt;
print type(soup.a)
#&lt;class 'bs4.element.Tag'&gt;

对于 Tag,它有两个重要的属性,是 name 和 attrs,分别为标签名字和属性:

print soup.p.attrs
#{'class': ['title'], 'name': 'dromouse'}
print soup.p['class']
#['title']

NavigableString是标签内部的文字。
获取<p>The Dormouse’s story</p>内的内容

print soup.p.string
#The Dormouse's story

BeautifulSoup

BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,

Comment

Comment 对象是一个特殊类型的 NavigableString 对象,代表注释,其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦。

print soup.a
print soup.a.string
print type(soup.a.string)

输出:

&lt;a class="sister" href="http://example.com/elsie" id="link1"&gt;&lt;!-- Elsie --&gt;&lt;/a&gt;
Elsie
&lt;class 'bs4.element.Comment'&gt;

搜索文档树

find_all( name , attrs , recursive , text , kwargs )
find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件
name 参数可以查找所有名字为 name 的tag,字符串对象会被自动忽略掉
如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以b开头的标签,这表示和
标签都应该被找到**

import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)
# body
# b

如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则返回 False。
下面方法校验了当前元素,如果包含 class 属性却不包含 id 属性,那么将返回 True:

def has_class_but_no_id(tag):
    return tag.has_attr('class') and not tag.has_attr('id')

将这个方法作为参数传入 find_all() 方法,将得到所有<p>标签:

soup.find_all(has_class_but_no_id)
# [&lt;p class="title"&gt;&lt;b&gt;The Dormouse's story&lt;/b&gt;&lt;/p&gt;,
#  &lt;p class="story"&gt;Once upon a time there were...&lt;/p&gt;,
#  &lt;p class="story"&gt;...&lt;/p&gt;]

其他还有很多用法。

css选择器

在 CSS 中,选择器是选取需设置样式的元素的模式。
Beautiful Soup支持大部分的CSS选择器。使用 Tag 或 BeautifulSoup 对象的 .select() 方法, 即可使用CSS选择器的语法找到想要的元素。
select_one是select的变体,它返回查找到的元素的第一个。
部分语法:

选择器 例子 例子描述
.class .intro 选择 class=“intro” 的所有元素。
#id #firstname 选择 id=“firstname” 的元素。
element p 选择所有 <p> 元素。
element>element div > p 选择父元素是 <div> 的所有 <p> 元素。

具体见CSS选择器参考手册

输出

如果只想得到结果字符串,不重视格式,那么可以对一个 BeautifulSoup 对象或 Tag 对象使用Python的 unicode() 或 str() 方法:

str(soup)
# '&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;\xe2\x80\x9cDammit!\xe2\x80\x9d he said.&lt;/body&gt;&lt;/html&gt;'

csdn网页内容

windows开发环境记录为例

  1. 主体
    在csdn博客中,真正的文章区域的div id为mainBox下的class为div.blog-content-box的div里面,获取的语句如下: ``` content = soup.select_one(“#mainBox > main > div.blog-content-box”)
1. 标题

<h1 class=”title-article” id=”articleContentId”>windows开发环境记录</h1>


class在主体内唯一

title=soup.select_one(“h1.title-article”)

1. 作者名字

<a class=”follow-nickName “ href=”https://blog.csdn.net/m0_37565736” target=”_blank” rel=”noopener”>香蕉割草机 </a>


class在主体内唯一

auth=soup.select_one(“a.follow-nickName”)

1. 创建时间

<span class=”time”>已于&nbsp;2022-03-26 16:06:49&nbsp;修改</span>


在html代码中,使用转义字符&amp;nbsp表示1个空格。<br/> class在主体内唯一

createtime=soup.select_one(“span.time”)

1. 分类和标签
分类的报文:

<a class=”tag-link” href=”https://blog.csdn.net/m0_37565736/category_7276991.html” target=”_blank” rel=”noopener”>其他 </a>


标签的:

<a data-report-click=”{…} class=”tag-link” href=”https://so.csdn.net/so/search/s.do?q=环境&amp;t=blog&amp;o=vip&amp;s=&amp;l=&amp;f=&amp;viparticle=” target=”_blank” rel=”noopener”>环境 </a>


代码入下:

candt=soup.select(“a.tag-link”) for t in candt: if t.has_attr(‘data-report-click’): tag.append(t.string) else: classify.append(t.string)

```

具体处理

post命名

Jekyll 要求一篇文章的文件名遵循下面的格式:

年-月-日-标题.MARKUP

考虑获取到文章后,获取这三个字段,作为文件名存储转换好的markdown文件。

头信息

每篇post的头部都包含 YAML 头信息,除了jekll已有的,也可以自己扩展。目前我使用so-simple-theme作为网站的主题,需要的头信息有:
title
categories
tags
这三个是必须的,代表标题,分类和标签。

防重复

后续考虑用文章id来区分,避免重复