鱼C论坛

 找回密码
 立即注册
查看: 1566|回复: 14

[已解决]请帮我排除一下bug,确实搞不定了。

[复制链接]
发表于 2018-2-27 16:49:05 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 柠檬树宝宝 于 2018-2-27 20:56 编辑

第一次学写程序,请高手帮我找解决bug, 希望能告诉我到底错在哪里,而不是重写,学习阶段过程比结果重要。
谢谢了。


  1. import urllib.request
  2. from bs4 import BeautifulSoup
  3. import time
  4. import re
  5. import random

  6. #将可重复使用的功能放到一起。

  7. class Getweb:
  8. # 统一定义user_Agent. 可复用
  9.     def __init__(self):
  10.         self.header={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36'}

  11. # 统一定义网页获取,将反复使用。
  12.     def getrep(self, url):
  13.         req = urllib.request.Request(url,headers=self.header)
  14.         resp = urllib.request.urlopen(req, timeout=5)
  15.         content = resp.read()
  16.         return content

  17. # 定义一个查询当前ip的方法,用于验证当前访问的ip
  18.     def getip(self,url):
  19.         print(url)
  20. #发现第二个错误,类里面的函数,如果需要调用,需要增加对象指针,此处,调用getrep()时,需要增加一个self.
  21. #发现第四个错误,获取的数据进行解码。
  22.         content = self.getrep(url).decode('utf-8')
  23.         r = r'<h2>(.*?)</h2>'
  24.         ipdz = re.findall(r,content)
  25.         return ipdz


  26. #获代理网站的免费IP数据,放到代理IP池
  27. class Xiciip:
  28.    
  29. #使用西祠ip代理. 抓取后的放到pool里面
  30.     def __init__(self, url):
  31.         self.pool = []
  32.         self.url = url
  33.         self.gethtml = Getweb()  #由于要复用公共类里面打开网页的方法,所以实例化一个对象处理。


  34. # 获取ip代理,放到pool里面, 其中复用了公共类里面打开网页的方法 getrep()
  35.     def find(self):
  36.         for i in range(1, 2):
  37.             content = self.gethtml.getrep(self.url + str(i))
  38.             soup = BeautifulSoup(content,'html.parser')
  39.             ips = soup.findAll('tr')
  40.             for x in range(2, len(ips)):
  41.                 ip = ips[x]
  42.                 tds = ip.findAll("td")
  43.                 if tds == []:
  44.                     continue
  45.                 ip_temp = tds[1].contents[0] + ":" + tds[2].contents[0]
  46.                 self.pool.append(ip_temp)
  47.         time.sleep(1)
  48.         return  self.pool



  49. #提供一个清洗IP数据方法,剔除不能使用的代理IP
  50. class Iptest:
  51. #  初始化,用whatismyip网站,查询当前访问ip. 要使用了公共类Getweb里面的getip()方法 和 getrep()方法
  52.   def __init__(self):
  53. #发现第三个错误,地址写错了,打一下耳光。
  54.         self.testurl ='http://www.whatismyip.com.tw'
  55. #发现一个错误,实例化类对象时候,无论类是否有参数,都需要加括号。即使定义类的时候没有括号。切记,切记!!
  56.         self.gethtml = Getweb()
  57.         print(self.testurl)

  58. # 测试ip的方法。要传入一个ip, 分别直接ip访问,获得本机ip, 然后用传入的ip访问,获得传入的ip.  如果能够访问,而且得到两个ip不同,则说明传入的代理ip可用。返回ture
  59.     def testip(self,ip):
  60.         myip = self.gethtml.getip(self.testurl)
  61.         try:
  62.             for i in range(2):
  63.                 proxy_support = urllib.request.ProxyHandler({"http": ip})
  64.                 opener = urllib.request.build_opener(proxy_support)
  65.                 urllib.request.install_opener(opener)
  66.                 dlip = self.gethtml.getip(self.testurl)

  67.                 if dlip != myip:
  68.                     return True
  69.         except:#
  70.             return False


  71. #对得到代理IP数据进行清洗后,分别提供单个IP输出、批量输出、按文件持久化存储
  72. class IPpool:
  73. # 初始化,需要传入一个ip pool (代理ip列表),由于要测试,所以实例化一个Iptest类的对象。
  74.     def __init__(self,pool):
  75.         self.pool = pool
  76.         self.test = Iptest()

  77. # 将传入的列表pool中的ip 分别拿到Iptest类的testip()方法进行测试. 不通过的剔除,得到一个新的 pool.
  78.     def get_ips(self):
  79.         for ip in self.pool:
  80.             if self.test.testip(ip):
  81.                 continue
  82.             else:
  83.                 self.pool.remove(ip)
  84.         return self.pool

  85. # 从pool 中随机拿一个ip来用。
  86.     def getoneip(self):
  87.         return random.choice(self.pool)

  88. #将pool 通过文件持久化存起来。 此方法暂时不用。
  89.     def writeToTxt(self,file_path):
  90.         try:
  91.             fp = open(file_path, "w+")
  92.             for item in self.pool:
  93.                 fp.write(str(item) + "\n")
  94.             fp.close()
  95.         except IOError:
  96.             print("fail to open file")




  97. ——————————————————————————————————————————————————————————————————————————

  98. import ipproxy as proxy
  99. #导入上面的模块
  100. import urllib.parse
  101. import urllib.request
  102. import json

  103. # 定义爬取有道词典网站的在线翻译服务,需要使用代理IP
  104. class Fanyi:
  105.    
  106. #初始化一下翻译的类

  107. def __init__(self,ipurl):
  108. #接受代理ip网站的url传入
  109.         self.ipurl = ipurl
  110. #复用公共类的方法,先实例一个对象出来。
  111.         self.header = proxy.Getweb()
  112. #调用实例化西祠类对象。
  113.         self.getdl = proxy.Xiciip(self.ipurl)
  114. #实例化一个Ippool类对象,通过将西祠类对象执行find()方法,得到pool,并作为参数传递进去
  115.         self.getip = proxy.IPpool(self.getdl.find())
  116. #再次实例化一个Ippool类对象,但是是将上一个Ippool类对象self.getip,再执行get_ips()方法后,得到的新pool传进去。后面代码从这个对象中执行getoneip()方法,拿ip用。
  117.         self.iproxy = proxy.IPpool(self.getip.get_ips())


  118. #抓起翻译网站服务的方法
  119.     def fanyi(self,yourtext):
  120.         youdao = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
  121.         data = {'from': 'AUTO', 'to': 'AUTO', 'client': 'fanyideskweb', 'smartresult': 'dict', 'doctype': 'json',
  122.                 'version': '2.1', 'keyfrom': 'fanyi.web', 'action': 'FY_BY_REALTIME', 'typoResult': 'false',
  123.                 'i': yourtext}
  124.         data = urllib.parse.urlencode(data).encode('utf-8')

  125. #这里使用代理ip,  self.iproxy.getoneip()
  126.         proxy_support = urllib.request.ProxyHandler({"http": self.iproxy.getoneip()})
  127.         opener = urllib.request.build_opener(proxy_support)
  128.         urllib.request.install_opener(opener)
  129. # 这里使用了公共类的header.   self.header已经申明是Getweb()类一个实例。它取该类的header属性。
  130.         req = urllib.request.Request(youdao, data,headers=self.header.header )
  131.         resp = urllib.request.urlopen(req, timeout=5)
  132.         fankui = resp.read().decode('utf-8')
  133.         target = json.loads(fankui)
  134.         translateResult = target["translateResult"][0][0]['tgt']
  135.         return translateResult


  136. #生成本地化的实时翻译应用

  137. xici='http://www.xicidaili.com/wn/'
  138. #实例化 Fanyi 类,传入代理ip网站地址
  139. lemon = Fanyi(ipurl = xici)
  140. a = ''
  141. #定义程序结束命令
  142. c = ['退出', 'exit', 'Exit', 'EXIT']
  143. while a not in (c):
  144.     a = input('爸爸说:')
  145.     if a in (c):
  146.         break
  147. #执行Fanyi 类的方法,传入值,得到翻译值。
  148.     b = lemon.fanyi(yourtext = a)
  149.     print('柠檬宝宝翻译:' + b)
  150. print('谢谢使用!')
复制代码

最佳答案
2018-2-27 20:48:22
这里要解码,不然不能用正则表达式搜索
1519735625(1).png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-2-27 17:01:02 | 显示全部楼层
  1. req = urllib.request.Request(url=youdao, data=data,headers=self.header.header )
复制代码

这一句写错了。
我就随便看了一下。

建议你运行一次报错了不明白再来问吧。
代码这么多又没有注释,别人要看完你的代码很麻烦的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-27 17:19:25 | 显示全部楼层
  self.iproxy = proxy.IPpool(self.getip.get_ips())   这句有问题。执行有问题。getip() 缺少url参数,但是在
myip = self.gethtml.getip(self.testurl)  执行之前,self.testurl 是可以打印输出的。

也就是说,如果直接拿爬到ip池去getoneip(),可以运行,不过可能会因为ip失效而报错。 增加这句,是想在得到的ip 池基础上,过滤一下无效的ip。通过先是get_ips(), 得到新的pool ,   然后再getoneip()
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-27 17:26:25 | 显示全部楼层
拿爬来的ip pool 作为参数,实例化一个对象getip,  然后用getip 执行 get_ips() 方法,得到过滤后的pool
拿过滤后的pool作为参数 ,再实体化一个对象ipproxy .    最后执行取ip的操作。 ipproxy.getoneip()

报错是说,get_ips(),方式执行时,调用myip = self.gethtml.getip(self.testurl)  没有传入uir参数。self.testurl  是有值的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-27 19:34:51 | 显示全部楼层
已经找到两个错误,但是还是有bug, 请高手帮忙排查一下吧。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-27 19:39:33 | 显示全部楼层
写成这样很厉害了,但是模块化思维是没错,你写的太过于繁琐,很多地方可以简洁一点,调试你这个程序思路还是很清晰,就是很累
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-27 19:45:18 | 显示全部楼层
你的测试IP函数方法出了问题,在打印myip时就已经打印不出来,说明你用正则表达式查找ip那一段错了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-27 19:57:05 | 显示全部楼层
headers 字典中,需要有Referer :url  吗?  open里面不是已经传了url 了吗,是不是重复了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-27 20:17:16 From FishC Mobile | 显示全部楼层
赶紧去看极客之速率革命,第三方模块,该有的的功能都有
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-27 20:31:59 | 显示全部楼层
waitforlove 发表于 2018-2-27 20:17
赶紧去看极客之速率革命,第三方模块,该有的的功能都有

结果不重要,过程最重要。如果运行成功,我就把他删掉。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-27 20:42:18 | 显示全部楼层
你这个whatsmyip的地址,前面居然是4个w,怪不得
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-27 20:48:22 | 显示全部楼层    本楼为最佳答案   
这里要解码,不然不能用正则表达式搜索
1519735625(1).png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-27 20:57:42 | 显示全部楼层
已修正,但是运行,循环输出whatsmyip的地址
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-27 21:08:48 | 显示全部楼层
打印html 结构和书上的不一样,立即修改抓取ip的方法。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-27 21:32:23 | 显示全部楼层
帮你重写了一下正则表达式,获取ip的方法,然后下面是获取的有用的ip,另外你每一次筛选都要调用一次
查询自我真实ip这很啰嗦,我就把它调到__init__里面去了
好累,后面的你自己搞定吧
1519738073(1).png
1519738147(1).png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-3-8 00:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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