getter.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. """
  2. -------------------------------------------------
  3. File Name: proxyGetter.py
  4. Description: 代理抓取模块,负责与网络的交互。
  5. 注意,代理网站的HTML结构可能会时常的更新,
  6. 会导致本文件下的抓取函数失效,所以,在运行
  7. 代理池之前,需要更新一下FreeProxyGetter类
  8. 中以crawl_开头的方法。
  9. Author: Liu
  10. Date: 2016/12/9
  11. -------------------------------------------------
  12. """
  13. import time
  14. from .utils import get_page
  15. from pyquery import PyQuery as pq
  16. class ProxyMetaclass(type):
  17. """
  18. 爬虫的元类,在FreeProxyGetter类中加入
  19. __CrawlFunc__和__CrawlFuncCount__
  20. 两个参数,分别表示爬虫函数,和爬虫函数的数量。
  21. """
  22. def __new__(cls, name, bases, attrs):
  23. count = 0
  24. attrs['__CrawlFunc__'] = []
  25. for k, v in attrs.items():
  26. if 'crawl_' in k:
  27. attrs['__CrawlFunc__'].append(k)
  28. count += 1
  29. attrs['__CrawlFuncCount__'] = count
  30. return type.__new__(cls, name, bases, attrs)
  31. class FreeProxyGetter(object, metaclass=ProxyMetaclass):
  32. """
  33. 代理爬虫,负责扫描各大代理网站,抓取代理。
  34. 该类有可扩展性,可根据需要自己添加新站点的代理抓取函数,
  35. 但是函数名必须以crawl_开头,返回值必须以"host:port"的形式返回,
  36. 添加器会自动识别并调用此类函数。
  37. """
  38. def get_raw_proxies(self, callback, count=40):
  39. proxies = []
  40. print('Callback', callback)
  41. for proxy in eval("self.{}()".format(callback)):
  42. proxies.append(proxy)
  43. return proxies
  44. def crawl_daili66(self, page_count=4):
  45. """
  46. 抓取代理66网的数据。
  47. """
  48. start_url = 'http://www.66ip.cn/{}.html'
  49. urls = [start_url.format(page) for page in range(1, page_count + 1)]
  50. for url in urls:
  51. print('Crawling', url)
  52. html = get_page(url)
  53. if html:
  54. doc = pq(html)
  55. trs = doc('.containerbox table tr:gt(0)').items()
  56. for tr in trs:
  57. ip = tr.find('td:nth-child(1)').text()
  58. port = tr.find('td:nth-child(2)').text()
  59. yield ':'.join([ip, port])
  60. def crawl_proxy360(self):
  61. """
  62. 抓取proxy360网的数据。
  63. """
  64. start_url = 'http://www.proxy360.cn/Region/China'
  65. print('Crawling', start_url)
  66. html = get_page(start_url)
  67. if html:
  68. doc = pq(html)
  69. lines = doc('div[name="list_proxy_ip"]').items()
  70. for line in lines:
  71. ip = line.find('.tbBottomLine:nth-child(1)').text()
  72. port = line.find('.tbBottomLine:nth-child(2)').text()
  73. yield ':'.join([ip, port])
  74. def crawl_goubanjia(self):
  75. start_url = 'http://www.goubanjia.com/free/gngn/index.shtml'
  76. html = get_page(start_url)
  77. if html:
  78. doc = pq(html)
  79. tds = doc('td.ip').items()
  80. for td in tds:
  81. td.find('p').remove()
  82. yield td.text().replace(' ', '')
  83. def crawl_haoip(self):
  84. start_url = 'http://haoip.cc/tiqu.htm'
  85. html = get_page(start_url)
  86. if html:
  87. doc = pq(html)
  88. results = doc('.row .col-xs-12').html().split('<br/>')
  89. for result in results:
  90. if result: yield result.strip()