python 自动生成 sitemap文件

󰃭 2017-03-02

什么是sitemap

很多时候, 我们新建的网站, 希望能被搜索引擎更好,更快的收录,

但搜索引擎并不知道我们网站的结构和内容, 对我们的网站的抓取并不是那么的快速和完善,导致网站的很多部分不能被及时收录

sitemap 就是这么一个东西, 他能引导搜索引擎收录我们网站中的页面链接, 就像sitemap的名字一样, 网站地图, 搜索引擎通过这个地图就能更好的收录网站内容了

那么, 我们如何完整的理解sitemap呢,

大家可以参考 https://www.sitemaps.org/zh_cn/index.html, 其中协议页面的简体中文有可能乱码, 大家可以切换到繁体版本查看

sitemap 的格式

sitemap一般有三种格式:txt,xml和Sitemap索引格式,

比如百度支持的sitemap格式说明文档: http://zhanzhang.baidu.com/college/courseinfo?id=267&page=2#h2_article_title0

我这里也简单说明下

txt格式

这种格式的文件中, 每个url一行,

http://www.example.com/repaste/101562698_5230191316.html
http://www.example.com/repaste/101586283_5230215075.html
http://www.example.com/repaste/101639435_5230310576.html 

xml格式

这种格式稍微复杂些, 但内容也不多

<?xml version="1.0" encoding="utf-8"?>
<!-- XML文件需以utf-8编码-->
<urlset>
<!--必填标签-->
    <url>
        <!--必填标签,这是具体某一个链接的定义入口,每一条数据都要用<url>和</url>包含在里面,这是必须的 -->
        <loc>http://www.yoursite.com/yoursite.html</loc>
        <!--必填,URL链接地址,长度不得超过256字节-->
        <lastmod>2009-12-14</lastmod>
        <!--可以不提交该标签,用来指定该链接的最后更新时间-->
        <changefreq>daily</changefreq>
        <!--可以不提交该标签,用这个标签告诉此链接可能会出现的更新频率 -->
        <priority>0.8</priority>
        <!--可以不提交该标签,用来指定此链接相对于其他链接的优先权比值,此值定于0.0-1.0之间-->
    </url>
    <url>
        <loc>http://www.yoursite.com/yoursite2.html</loc>
        <lastmod>2010-05-01</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.8</priority>
    </url>
</urlset>

各个标签对应的注释也说明了标签含义, 这种格式比txt格式表达的内容更丰富了

索引文件格式

这种严格来说只是一个索引多个sitemap文件的xml格式文件, 用于引导搜索引擎去多个sitemap文件中收录url。

一般来说, 只有当网站内容比较多的时候, 才会使用这种格式:

单个sitemap文件中允许包含的url数量是有限的(百度是5万个), 且单个sitemap文件大小也有限制(百度是10M)

这种情况下, 我们怎么处理sitemap呢: 这就用到了索引文件格式的sitemap, 我们可以把网站的 url 分别写入多个sitemap 文件, 比如

sitemap_1.xml
sitemap_2.xml
sitemap_3.xml

每个xml内容和格式参考 xml格式的sitemap

然后再用一个索引文件格式的sitemap 对以上文件进行索引即可(sitemap.xml):

<?xml version="1.0" encoding="utf-8"?>
<!-- XML文件需以utf-8编码-->
<sitemapindex>
<!--必填,以 <sitemapindex> 开始标记作为开始,以 </sitemapindex> 结束标记作为结束-->
    <sitemap>
        <!--必填,以<sitemap>标签提交一个子sitemap文件-->
        <loc>http://example.com/sitemap_3.xml</loc>
        <!--必填,识别sitemap的位置-->
        <lastmod>2009-12-16</lastmod>
        <!--选填,识别相对sitemap文件的修改时间-->
    </sitemap>
    <!--必填,标签闭合-->
    <sitemap>
        <loc>http://example.com/sitemap_2.xml</loc>
        <lastmod>2009-12-15</lastmod>
    </sitemap>
     <sitemap>
        <loc>http://example.com/sitemap_1.xml</loc>
        <lastmod>2009-12-14</lastmod>
    </sitemap>
</sitemapindex>
<!--必填,标签闭合-->

这样就能覆盖全站或者大部分站点的内容了

以上就是对sitemap的介绍说明, 那我们该如何生成我们自己的网站sitemap呢

这里我举个实例, 因为网站内容不多, 使用的是第二种xml格式的sitemap, 给各位参考

生成sitemap.xml

因为网站内容是以博客为主, 所以我的sitemap中就是博客的链接

生成sitemap.xml的过程分为两步

读取所有的博客链接和更新时间

博客是基于ID的链接, 格式如下:

https//www.xxx.com/blog/<id>

所以我需要从数据库中读取需要的文章的ID和更新时间

def blog_data(db_con):
    with db_con.cursor(pymysql.cursors.DictCursor) as cur:
        cur.execute('select id, mtime from article where status=1 order by mtime desc')
      
        return cur.fetchall()

拼接xml格式

然后拼接url, 与mtime一起构造xml格式内容

# 格式化sitemap.xml内容
def xml_format(rows):
    xml_content = '<?xml version="1.0" encoding="UTF-8"?><urlset>{}</urlset>'
    url_xmls = [url_xml(row) for row in rows]
    xml_content = xml_content.format("".join(url_xmls))
    return xml_content
    
# 单个url 的xml格式
def url_xml(row):
    id = row['id']
    # 时间戳格式化
    mtime = datetime.datetime.fromtimestamp(row['mtime']).strftime('%Y-%m-%d')
    url = "https//www.xxx.com/blog/{}".format(id)
    url_xml = '<url><loc>{}</loc><lastmod>{}</lastmod><changefreq>daily</changefreq><priority>0.8</priority></url>'
    url_xml = url_xml.format(url, mtime)
    return url_xml

写入sitemap文件

# 将sitemap 内容写入sitemap.xml文件
def xml_writer(file_name, xml_content):
    with open(file_name, 'w') as fh:
        fh.write(xml_content)
        fh.close()

组合调用

if __name__ == '__main__':
    db_con = pymysql.connect(
            host=DB_CONF['host'],
            user=DB_CONF['user'],
            port=DB_CONF['port'],
            passwd=DB_CONF['passwd'],
            db=DB_CONF['db'])
            
    rows = blog_data(db_con)
    xml_content = xml_format(rows)
    # 将sitemap 写入网站根目录的sitemap.xml
    xml_writer('/data/to/web/root/sitemap.xml', xml_content)

这就完成了对我的站点的sitemap.xml的生成, 基于此脚本, 每天定时更新即可

当然, 在第一次生成文件后, 我们需要将sitemap文件提交到百度, 百度会周期性的抓取检查您提交的Sitemap,对其中的链接进行处理。