apispider.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #-*-coding:utf-8-*-
  2. #支持中文必须加上上面一句话
  3. __author__ = 'Administrator'
  4. import scrapy
  5. #正则表达式模块
  6. import re
  7. #包含scrapy中的Request请求,在yield request中用到
  8. from scrapy.http import Request
  9. #引入将要保存到数据库的类名称
  10. from ApiCrawler.items import ApiItem
  11. class ApiSpider(scrapy.spiders.Spider):
  12. name = "api"
  13. #只爬api.1473.cn网址
  14. allowed_domains=["api.1473.cn"]
  15. #开始爬的网址
  16. start_urls=[
  17. "http://api.1473.cn"
  18. ]
  19. #目的是去除重复的url。
  20. URLS=[]
  21. #计数,一共爬了多少次
  22. count=0
  23. def parse(self, response):
  24. #allUrl=response.url
  25. #print allUrl
  26. #从response中获取内容,保存到数据库,为什么能保存到数据库呢?应该是架构写好的。
  27. #extract方法返回unicode字符串
  28. apiItem=ApiItem()
  29. apiItem['url'] = response.url
  30. # normalize-space 解决xpath取出的title值有很多回车空格的问题
  31. #text()函数获取标签下面的文本
  32. _titles=response.xpath(' normalize-space(/html/head/title/text())')
  33. if _titles:
  34. apiItem['title'] =_titles[0].extract()
  35. else:
  36. apiItem['title'] =""
  37. #获取meta中的content比较麻烦,国内居然没有资料。
  38. _keywords=response.xpath("//meta[@name='keywords']/@content")
  39. if _keywords:
  40. apiItem['keywords'] = _keywords[0].extract()
  41. else:
  42. apiItem['keywords'] = ""
  43. _description=response.xpath("//meta[@name='description']/@content")
  44. if _description:
  45. apiItem['description'] = _description[0].extract()
  46. else:
  47. apiItem['description']=""
  48. #首先获取body标签,然后再获取body标签中的所有字符串,为节约代码,下面使用三元操作符号,不熟悉的学生去学习一下三元
  49. #python的三元比较奇葩,估计是不入流程序员写的,h = "变量1" if a>b else "变量2"
  50. #_content=response.xpath('/html/body').xpath('string(.)').extract()[0];
  51. _content=response.xpath('/html/body').xpath('string(.)')
  52. #_content=response.xpath("//div[@class='book']").xpath('string(.)')
  53. apiItem['content']=_content[0].extract() if _content else ""
  54. yield apiItem
  55. # 下面的正则会提取页面中所有的后缀名为.aspx,.html .htm的超级链接,然后循环递归
  56. pattern=re.compile(r'((((https|http):\/\/)|\/)[0-9a-zA-Z\/\.@-_%]*?\.(aspx|html|htm))')
  57. urls=pattern.findall(response.text)
  58. for url in urls:
  59. #去除重复
  60. findUrl=url[0]
  61. if findUrl in self.URLS:
  62. continue
  63. else:
  64. self.URLS.append(findUrl)
  65. #Request对象需要包含from scrapy.http import Request
  66. #递归获取
  67. yield Request(findUrl,callback=self.parse)
  68. #filename=response.url.split("/")[2]
  69. #with open(filename,'wb') as f:
  70. # f.writable(response.body)