学习的是崔庆才的《python3网络开发实战》
代码与他写的基本相同,只是记录一下我遇到的问题以及解决方法。
1.初识metaclass元类
2.NameError:name 'Crowll_66' is not defined
3.xpath筛选在for语句里面的坑,以及yield列表输出
4.redis报错:'str' object has no attribute 'item'
5.mutiprocessing.Process(target=function)中的括号问题
(一):初识metaclass元类
关于这方面的介绍网上有很多,我还是新手,就不多解释了。放在这里单纯想提醒一下自己以后可以再看几遍。
(二):NameError:name 'Crowll_66' is not defined
这里遇到的问题是,在给参数直接传名字的时候会报错。
class shuxue():
def __init__(self):
self.ans = 0
def jiafa(self):
for i in range(10):
self.ans += 1
yield self.ans
def jisuan(self, call):
for a in eval("self.{}()".format(call)):
print(a)
if __name__ == '__main__':
run = shuxue()
run.jisuan(call = 'jiafa')
这段代码是将生成器yield放在了for循环当中,一开始引用他的时候,我写的代码是:call=jiafa
if __name__ == '__main__':
run = shuxue()
run.jisuan(call = jiafa)
然后就报错
不过变成字符串就解决问题了
(三):xpath筛选在for语句里面的坑,以及yield列表输出
书中用的是urllib库来做的,但是我还是比较喜欢xpath。
但是在for循环中出现了一些问题,代码如下:
class Crawl(object):
def get_proxies(self, name):
proxies = []
for proxy in eval("self.{}()".format(name)):
print('抓到代理', proxy)
proxies.append(proxy)
return proxies
def Crawl_66(self, page_count=4):
start_url = 'http://www.66ip.cn/{}.html'
urls = [start_url.format(page) for page in range(1, page_count + 1)]
for url in urls:
self.url = url
print('正在爬取', self.url)
r = requests.get(self.url)
html = etree.HTML(r.text)
trs = html.xpath('//tr')
for tr in trs:
ip = tr.xpath('//td[1]/text()')
td = tr.xpath('//td[2]/text()')
yield ':'.join([str(ip), str(td)])
if __name__ == '__main__':
awl = Crawl()
name = awl.get_proxies(name = 'Crawl_66')
我单独将代码进行运行测试。发现,输出是这样的
嗯?
问题有三个。
第一:前面两个是我不要的
第二:为什么每一遍都输出所有的
第三:yield输出的为什么冒号在中间,相当于将两个列表连在一起了
问题一解决:
for tr in trs[2:]:
问题二解决:
ip = tr.xpath('.//td[1]/text()')
td = tr.xpath('.//td[2]/text()')
注意,在最前面加了一个点.
问题三解决:
ip2str = [str(i) for i in ip]
strip = ''.join(ip2str)
td2str = [str(i) for i in td]
strtd = ''.join(td2str)
yield ':'.join([strip, strtd])
先将每个元素转换成字符串,然后再加入
(四):redis报错:'str' object has no attribute 'item'
解决方法:降redis的版本
(五):mutiprocessing.Process(target=function)中的括号问题
getter_process = multiprocessing.Process(target=self.getter_schedule())
getter_process.start()
这是错的,只需将target后的函数带的括号删除即可,即:
getter_process = multiprocessing.Process(target=self.getter_schedule)