黑帽联盟

 找回密码
 会员注册
查看: 1718|回复: 1
打印 上一主题 下一主题

[其它] 利用Python脚本生成sitemap.xml的实现方法

[复制链接]
yun 黑帽联盟官方人员 

920

主题

37

听众

1364

积分

超级版主

Rank: 8Rank: 8

  • TA的每日心情
    奋斗
    2019-10-18 11:20
  • 签到天数: 678 天

    [LV.9]以坛为家II

    本帖最后由 yun 于 2017-2-7 22:13 编辑

    最近项目中需要用脚本生成sitemap,中间学习了一下sitemap的格式和lxml库的用法。把结果记录一下,方便以后需要直接拿来用。下面这篇文章主要介绍了利用Python脚本生成sitemap.xml的实现方法,需要的朋友可以参考借鉴,一起来看看吧。

    安装lxml
    首先需要pip install lxml安装lxml库。
    如果你在ubuntu上遇到了以下错误:
    1. #include "libxml/xmlversion.h"
    2. compilation terminated.
    3. error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
    4. ----------------------------------------
    5. Cleaning up...
    6. Removing temporary dir /tmp/pip_build_root...
    7. Command /usr/bin/python -c "import setuptools, tokenize;__file__='/tmp/pip_build_root/lxml/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-O4cIn6-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /tmp/pip_build_root/lxml
    8. Exception information:
    9. Traceback (most recent call last):
    10. File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 122, in main
    11.   status = self.run(options, args)
    12. File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 283, in run
    13.   requirement_set.install(install_options, global_options, root=options.root_path)
    14. File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1435, in install
    15.   requirement.install(install_options, global_options, *args, **kwargs)
    16. File "/usr/lib/python2.7/dist-packages/pip/req.py", line 706, in install
    17.   cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False)
    18. File "/usr/lib/python2.7/dist-packages/pip/util.py", line 697, in call_subprocess
    19.   % (command_desc, proc.returncode, cwd))
    20. InstallationError: Command /usr/bin/python -c "import setuptools, tokenize;__file__='/tmp/pip_build_root/lxml/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-O4cIn6-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /tmp/pip_build_root/lxml
    复制代码
    请安装以下依赖:
    1. sudo apt-get install libxml2-dev libxslt1-dev
    复制代码
    Python代码
    下面是生成sitemap和sitemapindex索引的代码,可以按照需求传入需要的参数,或者增加字段:
    1. #!/usr/bin/env python
    2. # -*- coding:utf-8 -*-

    3. import io
    4. import re
    5. from lxml import etree


    6. def generate_xml(filename, url_list):
    7.   """Generate a new xml file use url_list"""
    8.   root = etree.Element('urlset',
    9.              xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
    10.   for each in url_list:
    11.     url = etree.Element('url')
    12.     loc = etree.Element('loc')
    13.     loc.text = each
    14.     url.append(loc)
    15.     root.append(url)

    16.   header = u'<?xml version="1.0" encoding="UTF-8"?>\n'
    17.   s = etree.tostring(root, encoding='utf-8', pretty_print=True)
    18.   with io.open(filename, 'w', encoding='utf-8') as f:
    19.     f.write(unicode(header+s))


    20. def update_xml(filename, url_list):
    21.   """Add new url_list to origin xml file."""
    22.   f = open(filename, 'r')
    23.   lines = [i.strip() for i in f.readlines()]
    24.   f.close()

    25.   old_url_list = []
    26.   for each_line in lines:
    27.     d = re.findall('<loc>(http:\/\/.+)<\/loc>', each_line)
    28.     old_url_list += d
    29.   url_list += old_url_list

    30.   generate_xml(filename, url_list)


    31. def generatr_xml_index(filename, sitemap_list, lastmod_list):
    32.   """Generate sitemap index xml file."""
    33.   root = etree.Element('sitemapindex',
    34.              xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
    35.   for each_sitemap, each_lastmod in zip(sitemap_list, lastmod_list):
    36.     sitemap = etree.Element('sitemap')
    37.     loc = etree.Element('loc')
    38.     loc.text = each_sitemap
    39.     lastmod = etree.Element('lastmod')
    40.     lastmod.text = each_lastmod
    41.     sitemap.append(loc)
    42.     sitemap.append(lastmod)
    43.     root.append(sitemap)

    44.   header = u'<?xml version="1.0" encoding="UTF-8"?>\n'
    45.   s = etree.tostring(root, encoding='utf-8', pretty_print=True)
    46.   with io.open(filename, 'w', encoding='utf-8') as f:
    47.     f.write(unicode(header+s))


    48. if __name__ == '__main__':
    49.   urls = ['http://www.baidu.com'] * 10
    50.   mods = ['2004-10-01T18:23:17+00:00'] * 10
    51.   generatr_xml_index('index.xml', urls, mods)
    复制代码
    效果
    生成的效果应该是这种格式:
    sitemap格式:
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    3. <url>
    4.   <loc>http://www.example.com/foo.html</loc>
    5. </url>
    6. </urlset>
    复制代码
    sitemapindex格式:
    1. <?xml version="1.0" encoding="UTF-8"?>
    2.   <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    3.   <sitemap>
    4.    <loc>http://www.example.com/sitemap1.xml.gz</loc>
    5.    <lastmod>2017-02-01T18:23:17+00:00</lastmod>
    6.   </sitemap>
    7.   <sitemap>
    8.    <loc>http://www.example.com/sitemap2.xml.gz</loc>
    9.    <lastmod>2017-02-01</lastmod>
    10.   </sitemap>
    11.   </sitemapindex>
    复制代码
    lastmod时间格式的问题
    格式是用ISO 8601的标准,如果是linux/unix系统,可以使用以下函数获取
    1. def get_lastmod_time(filename):
    2.   time_stamp = os.path.getmtime(filename)
    3.   t = time.localtime(time_stamp)
    4.   # return time.strftime('%Y-%m-%dT%H:%M:%S+08:00', t)
    5.   return time.strftime('%Y-%m-%dT%H:%M:%SZ', t)
    复制代码
    优化
    一般来说,用lxml效率低并且内存占用比较大,可以直接用文件的write方法创建。
    1. def generate_xml(filename, url_list):
    2.   with gzip.open(filename,"w") as f:
    3.     f.write("""<?xml version="1.0" encoding="utf-8"?>
    4. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n""")
    5.     for i in url_list:
    6.       f.write("""<url><loc>%s</loc></url>\n"""%i)
    7.     f.write("""</urlset>""")


    8. def append_xml(filename, url_list):
    9.   with gzip.open(filename, 'r') as f:
    10.     for each_line in f:
    11.       d = re.findall('<loc>(http:\/\/.+)<\/loc>', each_line)
    12.       url_list.extend(d)

    13.     generate_xml(filename, set(url_list))


    14. def modify_time(filename):
    15.   time_stamp = os.path.getmtime(filename)
    16.   t = time.localtime(time_stamp)
    17.   return time.strftime('%Y-%m-%dT%H:%M:%S:%SZ', t)


    18. def new_xml(filename, url_list):
    19.   generate_xml(filename, url_list)
    20.   root = dirname(filename)

    21.   with open(join(dirname(root), "sitemap.xml"),"w") as f:
    22.     f.write('<?xml version="1.0" encoding="utf-8"?>\n<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n')
    23.     for i in glob.glob(join(root,"*.xml.gz")):
    24.       lastmod = modify_time(i)
    25.       i = i[len(CONFIG.SITEMAP_PATH):]
    26.       f.write("<sitemap>\n<loc>http:/%s</loc>\n"%i)
    27.       f.write("<lastmod>%s</lastmod>\n</sitemap>\n"%lastmod)
    28.     f.write('</sitemapindex>')
    复制代码
    总结
    以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用python能带来一定的帮助

    帖子永久地址: 

    黑帽联盟 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与黑帽联盟享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和黑帽联盟的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、黑帽联盟管理员和版主有权不事先通知发贴者而删除本文

    148

    主题

    9

    听众

    337

    积分

    版主

    Rank: 7Rank: 7Rank: 7

  • TA的每日心情
    擦汗
    2018-6-6 11:33
  • 签到天数: 348 天

    [LV.8]以坛为家I

    python精髓哈
    来自安卓客户端来自安卓客户端
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 会员注册

    发布主题 !fastreply! 收藏帖子 返回列表 搜索
    回顶部