鱼C论坛

 找回密码
 立即注册
查看: 2467|回复: 3

一段爬虫代码,不明白错在哪里了

[复制链接]
发表于 2017-10-22 23:05:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 小明EVO 于 2017-10-23 18:12 编辑
  1. import io
  2. import formatter
  3. import html.parser
  4. import http.client
  5. import os
  6. import sys
  7. import urllib.parse, urllib.request

  8. class Retriever(object):
  9.     __slots__ = ('url', 'file')
  10.     def __init__(self, url):
  11.         self.url, self.file = self.get_file(url)

  12.     def get_file(self, url, default='index.html'):
  13.         'Create usable lacal fielname from URL'
  14.         parsed = urllib.parse.urlparse(url)
  15.         host = parsed.netloc.split('@')[-1].split(':')[0]
  16.         filepath = '%s%s' % (host, parsed.path)
  17.         if not os.path.splitext(parsed.path)[1]:
  18.             filepath = os.path.join(filepath, default)
  19.         linkdir = os.path.dirname(filepath)
  20.         if not os.path.isdir(linkdir):
  21.             if os.path.exists(linkdir):
  22.                 os.unlink(linkdir)
  23.             os.makedirs(linkdir)
  24.         return url, filepath

  25.     def download(self):
  26.         'Download URL to specific named file'
  27.         try:
  28.             retval = urllib.request.urlretrieve(self.url, self.file)
  29.         except (IOError, http.client.InvalidURL) as e:
  30.             retval = (('***ERROR: BAD URL "%s": %s ' % (self.url, e)),)
  31.         return retval

  32.     def parse_links(self):
  33.         'Parse out the links found in downloaded HTML file'
  34.         with open(self.file, 'r') as f:
  35.             data = f.read()
  36.         parser = html.parser.HTMLParser(formatter.AbstractFormatter(
  37.             formatter.DumbWriter(io.StringIO())))
  38.         parser.feed(data)
  39.         parser.close()
  40.         return parser.anchorlist

  41. class Crawler(object):
  42.     count = 0

  43.     def __init__(self, url):
  44.         self.q = [url]
  45.         self.seen = set()
  46.         parsed = urllib.parse.urlparse(url)
  47.         host = parsed.netloc.split('@')[-1].split(':')[0]
  48.         self.dom = '.'.join(host.split('.')[-2:])

  49.     def get_page(self, url, media=False):
  50.         'Download page and parse links, add to queue if nec'
  51.         r = Retriever(url)
  52.         fname = r.download()[0]
  53.         if fname[0] == '*':
  54.             print(fname, '... skipping parse')
  55.             return
  56.         Crawler.count += 1
  57.         print('\n(', Crawler.count, ')')
  58.         print('URL:', url)
  59.         print('FILE:', fname)
  60.         self.seen.add(url)
  61.         ftype = os.path.splitext(fname)[1]
  62.         if ftype not in ('.htm', '.html'):
  63.             return

  64.         for link in r.parse_links():
  65.             if link.startswith('mailto'):
  66.                 print('... discarded, mailto link')
  67.                 continue
  68.                 #忽略邮箱链接
  69.             if not media:
  70.                 ftype = os.path.splitext(link)[1]
  71.                 if ftype in ('.mp3', '.mp4', '.m4v', '.wav'):
  72.                     print('... discarded, media file')
  73.                     continue
  74.                     #忽略媒体文件
  75.             if not link.startswith('http://'):
  76.                 link = urllib.parse.urljoin(url, link)
  77.             print('*', link, )
  78.             #补全并打印正确的url
  79.             if link not in self.seen:
  80.                 if self.dom not in link:
  81.                     print('... discarded, not in domain')
  82.                 else:
  83.                     if link not in self.q:
  84.                         self.q.append(link)
  85.                         print('... new, added to Q')
  86.                     else:
  87.                         print('... discarded, already in Q')
  88.             else:
  89.                     print('... discarded, already processed')

  90.     def go(self, media=False):
  91.         'Process next page in queue (if any)'
  92.         while self.q:
  93.             url = self.q.pop()
  94.             self.get_page(url, media)

  95. def main():
  96.     if len(sys.argv) > 1:
  97.         url = sys.argv[1]
  98.     else:
  99.         try:
  100.             url = 'http://www.null.com/home/index.html'
  101.         except KeyboardInterrupt as EOFError:
  102.             url = ''
  103.     if not url:
  104.         return
  105.     if not url.startswith('http://') and \
  106.         not url.startswith('ftp://'):
  107.         url = 'http://%s/' % url
  108.     robot = Crawler(url)
  109.     robot.go()

  110. if __name__ == '__main__':
  111.     main()
复制代码

这是核心编程第三版里的爬虫的例子,基本是照着敲了一遍,只不过原来是2我改成了3,报错如下:
  1. ( 1 )
  2. URL: [url]http://www.null.com/home/index.html[/url]
  3. FILE: [url]www.null.com/home/index.html[/url]
  4. Traceback (most recent call last):
  5.   File "C:/Users/77409/PycharmProjects/untitled/crawl.py", line 122, in <module>
  6.     main()
  7.   File "C:/Users/77409/PycharmProjects/untitled/crawl.py", line 119, in main
  8.     robot.go()
  9.   File "C:/Users/77409/PycharmProjects/untitled/crawl.py", line 103, in go
  10.     self.get_page(url, media)
  11.   File "C:/Users/77409/PycharmProjects/untitled/crawl.py", line 72, in get_page
  12.     for link in r.parse_links():
  13.   File "C:/Users/77409/PycharmProjects/untitled/crawl.py", line 41, in parse_links
  14.     formatter.DumbWriter(io.StringIO())))
  15. TypeError: __init__() takes 1 positional argument but 2 were given
复制代码


我就不懂了。。。init返回的参数数量怎么和这里41行有关了。。。而且到底返回值是啥,怎么就数量不对了。。。求解
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-10-22 23:19:30 | 显示全部楼层
是这样的这个参数使用的是命令行参数,假设你这个代码名师crawer.py
那么在cmd下面
python crawer.py url
这样,取crawer.py后面的第一个参数为url
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-23 08:49:47 | 显示全部楼层
Teagle 发表于 2017-10-22 23:19
是这样的这个参数使用的是命令行参数,假设你这个代码名师crawer.py
那么在cmd下面
python crawer.py url ...

可是,parse_link不是只在下面72行的判断语句中用到了吗,没有要他给init啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-23 18:19:12 | 显示全部楼层
核心编程这本书的例子好像都有点问题啊,有没有人看过啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-12-25 12:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表