设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
楼主: manhong2112
打印 上一主题 下一主题

新人報到

[复制链接]

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

41#
发表于 2016-8-16 14:50:14 |只看该作者
Skeel 发表于 2016-8-15 22:13
做的很好,不過請問代碼編輯器是怎麼弄出來。

回帖里的代码编辑器?
有个 <> 图标的按钮
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

1

主题

0

好友

207

积分

中级会员

Rank: 3Rank: 3

42#
发表于 2016-8-22 15:28:39 |只看该作者
本帖最后由 manhong2112 于 2016-8-22 16:00 编辑

寫了一個爬蟲, 一開始用lxml總是報錯(貌似是網站的HTML有問題)...就轉用BeautifulSoup了...
雖然能用, 但總感覺哪裡不太對勁..
EDIT: 相對路徑沒被簡化, 組成了一個迴圈....
EDIT: 找到了urljoin這函數, 希望不再出bug

  1. # from lxml import etree
  2. from bs4 import BeautifulSoup
  3. import urllib as request
  4. from urlparse import urljoin
  5. import re
  6. import os


  7. def getHtml(url):
  8.     res = request.urlopen(url)
  9.     try:
  10.         return url, res.read().decode("utf-8")
  11.     except Exception:
  12.         return url, res.read().decode("big5")


  13. def extractLink(url, html):
  14.     soup = BeautifulSoup(html, "html.parser")
  15.     return set(map(lambda i: re.sub("#.*$", "", urljoin(url, i["href"])), soup.findAll('a')))
  16.     # return set(etree.HTML(html).xpath("//a/@href"))


  17. target = "http://example.com/" # 目標網站
  18. startAt = "http://example.com/index.html" # 起始網頁
  19. output = "output" # 輸出
  20. downloadedLink = set()
  21. toBeDownload = set()
  22. toBeDownload.add(startAt)
  23. p = re.compile("https?://.*?/(.*)")

  24. while len(toBeDownload) != 0:
  25.     try:
  26.         url = toBeDownload.pop()
  27.         downloadedLink.add(url)
  28.         if (url.startswith("http") or url.startswith("https")) and not url.startswith(target):
  29.             continue
  30.         print "Downloading " + url
  31.         _, content = getHtml(url)
  32.         m = re.match(p, url)
  33.         m = m.group(1)
  34.         path, file = os.path.split(m)
  35.         try:
  36.             os.makedirs(os.path.join(output, path))
  37.         except Exception:
  38.             pass
  39.         with open(os.path.join(output, m), "w") as f:
  40.             f.write(content.encode('utf8'))
  41.         newUrl = extractLink(url, content).difference(downloadedLink)
  42.         toBeDownload = toBeDownload.union(newUrl)
  43.     except Exception:
  44.         print "Failed to Download " + url
复制代码
回复

使用道具 举报

1

主题

0

好友

207

积分

中级会员

Rank: 3Rank: 3

43#
发表于 2016-10-10 21:00:38 |只看该作者
本帖最后由 manhong2112 于 2016-10-21 17:32 编辑

原本想弄個筆記本, 然後架個站自用...然後寫着寫着寫成了vcs(算嗎?算吧)......
話說混亂到自己都看不太下去了XDDD
EDIT: 換成if-else...感覺不想再看到python的lambda了....
EDIT: 大改了一下, 和把index的rollback功能刪了
  1. import hashlib
  2. import os
  3. import json
  4. import datetime
  5. import time

  6. dataLoc = "data"

  7. class Enitiy(object):

  8.     def __init__(self, name, dtype, hashcode, history):
  9.         self.name = name
  10.         self.dtype = dtype
  11.         self.hashcode = hashcode
  12.         self.history = history

  13. class Index(Enitiy):

  14.     def __init__(self, name, jsons=None, hashcode=None):
  15.         self.name = name
  16.         self.index = dict()
  17.         if jsons is not None:
  18.             for i in jsons["index"]:
  19.                 if i["type"] == "Index":
  20.                     self.index[i["name"]] = Index(
  21.                         i["name"],
  22.                         json.loads(read(i["hashcode"])),
  23.                         i["hashcode"])
  24.                 else:
  25.                     self.index[i["name"]] = Enitiy(
  26.                         i["name"],
  27.                         i["type"],
  28.                         i["hashcode"],
  29.                         i["history"] if "history" in i else dict())

  30.         super().__init__(name, "Index", hashcode, None)

  31.     def __str__(self):
  32.         return str(self.index)

  33.     def __getitem__(self, k):
  34.         return self.index[k]

  35.     def __setitem__(self, k, v):
  36.         self.index[k] = v

  37.     def __contains__(self, item):
  38.         return item in self.index

  39.     def __len__(self):
  40.         return len(self.index)

  41.     def items(self):
  42.         return self.index.items()

  43.     def dumpJsons(self):
  44.         result = dict()
  45.         result["index"] = []
  46.         result["name"] = self.name
  47.         for k, v in self.index.items():
  48.             obj = dict()
  49.             obj["name"], obj["type"], obj["hashcode"], obj["history"] = v.name, v.dtype, v.hashcode, v.history
  50.             result["index"].append(obj)
  51.         return json.dumps(result)

  52. _open = open
  53. def open(hashcode, type="w+"):
  54.     path = getPath(hashcode)
  55.     os.makedirs(os.path.dirname(path), exist_ok=True)
  56.     if os.path.isfile(path):
  57.         type = "r+"
  58.     else:
  59.         type = "w"
  60.     return _open(path, type, encoding="UTF-8")

  61. def getPath(hashcode):
  62.     return os.path.join(dataLoc, hashcode[:2], hashcode)

  63. def hash(str):
  64.     return hashlib.sha1(str).hexdigest()

  65. def hashStr(str):
  66.     return hash(str.encode("utf-8"))

  67. def hashFile(name, content):
  68.     return hash((name + "|" + content).encode("utf-8"))

  69. def read(hashcode):
  70.     with open(hashcode) as f:
  71.         return f.read()

  72. def init():
  73.     root = None
  74.     path = getPath("root")

  75.     name = "/"

  76.     if not os.path.isfile(path):
  77.         root = Index(name)
  78.         root_json = root.dumpJsons()
  79.         hashcode = hashFile(name, root_json)
  80.         with open(hashcode) as f:
  81.             f.write(root_json)
  82.         with open("root") as f:
  83.             f.write(json.dumps({"hashcode": hashcode, "name": name, "type": "Index"}))
  84.     else:
  85.         with open("root") as f:
  86.             accessPt = json.loads(f.read())
  87.             hashcode = accessPt["hashcode"]
  88.             with open(hashcode) as f:
  89.                 root = Index(name, json.loads(f.read()), hashcode)
  90.     return [root]

  91. def end(indexStack):
  92.     root = indexStack[0]
  93.     date = datetime.datetime.now().strftime("%Y/%m/%d-%H:%M:%S")
  94.     name = "/"
  95.     content = root.dumpJsons()
  96.     hashcode = hashFile(name, content)
  97.     with open(hashcode) as f:
  98.         f.write(content)
  99.     with open("root") as f:
  100.         accessPt = json.loads(f.read())
  101.         f.seek(0)
  102.         accessPt["hashcode"] = hashcode
  103.         f.write(json.dumps(accessPt))
  104.         f.truncate()

  105. helpCmd = {
  106.     "update": ["Usage>> update <name> <type> <content>",
  107.                "Usage>> Update or create a file"],
  108.     "rollback": ["Usage>> rollback <name> <id>",
  109.                  "Usage>> Rollback to the specified id"],
  110.     "ls": ["Usage>> ls [name]",
  111.            "Usage>> list all file in current dir or specified dir"],
  112.     "cd": ["Usage>> cd <dir|'..'>",
  113.            "Usage>> cd to specified dir"],
  114.     "mkdir": ["Usage>> mkdir <dir>",
  115.               "Usage>> create a new dir at current dir"],
  116.     "read": ["Usage>> read <name>",
  117.              "Usage>> read the content of specified file"],
  118.     "history": ["Usage>> history <name>",
  119.                 "Usage>> List modifiy history of specified file"],
  120.     "help": ["Usage>> <cmd>", "Usage>> Print the usage of cmd",
  121.              "Usage>> all cmd[update, rollback, ls, cd, mkdir, read, history, help]"]
  122. }
  123. mainCmd = {"update", "rollback", "ls", "cd",
  124.            "mkdir", "read", "history", "help", }

  125. def update(indexStack, name, dtype, content):
  126.     index = indexStack[-1]
  127.     date = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
  128.     dateid = hashStr(date)[:6]
  129.     entity_hashcode = hashFile(name, content)

  130.     with open(entity_hashcode) as f:
  131.         f.write(content)

  132.     if name not in index:
  133.         if dtype == "Index":
  134.             index[name] = Index(name, hashcode=entity_hashcode)
  135.         else:
  136.             index[name] = Enitiy(name, dtype, entity_hashcode, dict())
  137.     else:
  138.         entity = index[name]
  139.         entity.history[dateid] = (date, entity.hashcode)
  140.         entity.hashcode = entity_hashcode

  141. def rollback(indexStack, name, datetimeid):
  142.     """
  143.     indexStack
  144.     name = file/dir name
  145.     datetimeid = date
  146.     """
  147.     index = indexStack[-1]
  148.     assert type(index[name]) is not Index
  149.     history = index[name].history
  150.     assert datetimeid in history
  151.     with open(history[datetimeid][1]) as f:
  152.         update(indexStack, name, index[name].dtype, f.read())

  153. def ls(indexStack, name=None):
  154.     if name is not None:
  155.         index = Index(name, json.loads(read(indexStack[-1][name].hashcode)))
  156.     else:
  157.         index = indexStack[-1]
  158.     assert type(index) is Index
  159.     return index.name, sorted([(e.name, e.dtype) for _, e in index.items()])
  160.    
  161. def cd(indexStack, name):
  162.     """
  163.     indexStack
  164.     name = file/dir name
  165.     """
  166.     assert type(indexStack) is list
  167.     assert type(name) is str
  168.     if name == "..":
  169.         indexStack.pop()
  170.     else:
  171.         index = indexStack[-1]
  172.         assert type(index[name]) is Index
  173.         indexStack.append(index[name])

  174. def getHistory(indexStack, name):
  175.     """
  176.     indexStack
  177.     name = file name
  178.     """
  179.     assert type(indexStack) is list
  180.     assert type(name) is str
  181.     index = indexStack[-1]
  182.     assert type(index[name]) is not Index
  183.     return index[name].history

  184. def mkdir(indexStack, name):
  185.     assert name not in indexStack[-1]
  186.     update(indexStack, name, "Index", Index(name).dumpJsons())

  187. if __name__ == '__main__':
  188.     indexStack = init()
  189.     try:
  190.         while True:
  191.             cmd = input("/".join([i.name for i in indexStack]) + ">> ").split(" ")
  192.             args = cmd[1:] if len(cmd) > 1 else []
  193.             if cmd[0] in mainCmd:
  194.                 if cmd[0] == "update":
  195.                     update(indexStack, *args)
  196.                 elif cmd[0] == "rollback":
  197.                     rollback(indexStack, args[0], args[1])
  198.                 elif cmd[0] == "ls":
  199.                     if len(args) == 1:
  200.                         i = ls(indexStack, *args)
  201.                     else:
  202.                         i = ls(indexStack)
  203.                     print(i[0] + " :"),
  204.                     print("\n".join(["\t" + n + " | " + t for n, t in i[1]]))
  205.                 elif cmd[0] == "cd":
  206.                     cd(indexStack, *args)
  207.                 elif cmd[0] == "mkdir":
  208.                     if len(args) != 1:
  209.                         print("E>")
  210.                     else:
  211.                         mkdir(indexStack, args[0])
  212.                 elif cmd[0] == "read":
  213.                     if len(args) != 1:
  214.                         print("E>")
  215.                     else:
  216.                         print(read(indexStack[-1][args[0]].hashcode)),
  217.                 elif cmd[0] == "history":
  218.                     if len(args) == 1:
  219.                         history = getHistory(indexStack, args[0])
  220.                         print(args[0] + " :")
  221.                         print("id\t|date")
  222.                         print("\n".join(
  223.                              ["{}\t|{}".format(x[0], x[1]) for x in
  224.                                sorted([(dateid, v[0]) for dateid, v in history.items()], key=lambda x: x[1])]))
  225.                     else:
  226.                         print("E>")
  227.                 elif cmd[0] == "help":
  228.                     exit = False
  229.                     while not exit:
  230.                         cmd = input("Help>> ")
  231.                         if cmd == "exit" or cmd == "quit":
  232.                             exit = True
  233.                         elif cmd in helpCmd:
  234.                             list(map(lambda x: print(x), helpCmd[cmd]))
  235.                         else:
  236.                             print("E> Invalid command")
  237.             elif cmd[0] == "exit" or cmd[0] == "quit":
  238.                 break
  239.             else:
  240.                 print("E> Invalid command")
  241.     except Exception:
  242.         raise
  243.     finally:
  244.         end(indexStack)
复制代码
回复

使用道具 举报

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

44#
发表于 2016-10-11 09:54:18 |只看该作者
manhong2112 发表于 2016-10-10 21:00
原本想弄個筆記本, 然後架個站自用...然後寫着寫着寫成了vcs(算嗎?算吧)......
話說混亂到自己都看不太下去 ...

你厉害的
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

1

主题

0

好友

207

积分

中级会员

Rank: 3Rank: 3

45#
发表于 2016-10-14 19:58:04 |只看该作者
和之前的筆記本一系列的, 用來抽取指定網址的內容!
目前只做了知乎, 以後再慢慢拓展
#註解掉的是md轉html的
  1. from bs4 import BeautifulSoup
  2. import urllib.request as urllib
  3. import re
  4. #import markdown


  5. def getContext(url):
  6.     data = parse(url, getRule(url))
  7.     md = """\
  8. {title}
  9. {author}
  10. {url}

  11. {content}\
  12. """.format(
  13.         title=("#" + data["title"]) if "title" in data else "",
  14.         author=("###" + data["author"]) if "author" in data else "",
  15.         url=("#####[Link](" + data["url"] + ")") if "url" in data else "",
  16.         content=("<hr><br>" + data["content"]) if "content" in data else "")
  17.     #return "<meta charset='UTF-8'>\n" + markdown.markdown(md, output_format="html5")
  18.     return md

  19. rule = [
  20.     (re.compile(r"https?://www.zhihu.com/question/\d*?/answer/\d*?#?.*"),
  21.      {"content": {"selector": "div#zh-question-answer-wrap .zm-editable-content"},
  22.       "title": {"selector": "div#zh-question-title > h2.zm-item-title > a"},
  23.       "author": {"selector": "span.author-link-line > a.author-link"},
  24.       "url": {"selector": "meta['http-equiv'='mobile-agent']", "attr": "content", "matching": re.compile(".*url=(.*)")}
  25.       })
  26. ]


  27. def getRule(url):
  28.     for k, v in rule:
  29.         if k.match(url):
  30.             return v


  31. def getHtml(url, encoding="utf-8"):
  32.     res = urllib.urlopen(url)
  33.     return res.read()


  34. def parse(url, rule):
  35.     result = dict()
  36.     soup = BeautifulSoup(getHtml(url), "html.parser")
  37.     for (k, v) in rule.items():
  38.         content = None
  39.         if "attr" in v:
  40.             content = str(soup.select(v["selector"])[0][v["attr"]]).strip(' \t\n\r')
  41.         else:
  42.             content = str(soup.select(v["selector"])[0].get_text()).strip(' \t\n\r')
  43.         if "matching" in v:
  44.             m = v["matching"].match(content)
  45.             if m:
  46.                 result[k] = m.group(1)
  47.         else:
  48.             result[k] = content
  49.     return result

  50. print(getContext("http://www.zhihu.com/question/51266789/answer/125952575"))
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-4-19 13:04 , Processed in 0.032330 second(s), 20 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部