一、调用封装的Url_ProxyHelper类,源码如下
1 import urllib.request as ur 2 3 class Url_ProxyHelper: 4 def __init__(self, url, proxy_add, savepath=None): 5 self.url = url 6 self.proxy_add = proxy_add 7 self.req = None 8 self.proxy = None 9 self.opener = None 10 self.info = None 11 self.save_path = savepath 12 13 # 报头代理设置 14 def set_UrlAndProxy(self): 15 # 添加报头 16 self.req = ur.Request(self.url) 17 self.req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0') 18 19 # 设置代理服务器 20 self.proxy = ur.ProxyHandler({'http': self.proxy_add}) 21 self.opener = ur.build_opener(self.proxy, ur.HTTPHandler) 22 ur.install_opener(self.opener) 23 return self.req 24 25 # 数据存档 26 def save_InFile(self): 27 self.req = self.set_UrlAndProxy() 28 self.info = ur.urlopen(self.req).read() 29 open(self.save_path, 'wb').write(self.info) 30 31 # 数据返回 32 def feedbak_info(self): 33 self.req = self.set_UrlAndProxy() 34 self.info = ur.urlopen(self.req).read().decode('utf-8') # decode()用来解码,特别是中文 35 return str(self.info)
二、爬取源码
1 import urllib.request as ur 2 import re 3 from Url_ProxyHelper import Url_ProxyHelper 4 5 # 构造了一个去除Tags的函数 6 def delete_Tags(content, pattern): 7 return re.sub(pattern, "", content.replace(" ", "")) 8 9 10 # 设置目标网址 11 url = ur.quote("https://www.qiushibaike.com/", safe='/:?=', encoding='utf-8') 12 # 设置代理服务器IP 13 proxy_add = "114.239.147.6:808" 14 15 # 调用Url_ProxyHelper类 16 uph = Url_ProxyHelper(url, proxy_add) 17 info = uph.feedbak_info() 18 19 # 设置正则表达式 20 pattern_1 = 'target="_blank" title="(.*?)">' 21 pattern_2 = 'class="content">(.*?)</div>' 22 pattern_3 = '<(.*?)>' 23 24 # 匹配数据 25 user_list = re.compile(pattern=pattern_1, flags=re.S).findall(info) 26 content_list = re.compile(pattern=pattern_2, flags=re.S).findall(info) 27 28 for user, content in zip(user_list, content_list): 29 data = { 30 "user": user, 31 "content": delete_Tags(content, pattern_3) 32 } 33 print("用户是:" + data["user"]) 34 print("内容是:" + data["content"])
三、一点总结
1.关于urllib.request.urlopen("www.x.com").read()是否调用decode("utf-8")。
答:一般而言,当我们抓取一个页面需要将该信息存档(如存为x.html文件)时,这个时候不能调用decode()函数;而当我们需要读取页面的信息时(这里指的是抓取页面部分内容),存在信息的转码,所以这个时候需要调用decode()函数。
2.在正则表达式的使用过程中,需要注意,re.compile(pattern).findall(info)中的info必须是str类型,所有当出现报错时,需要稍微转换一下。
3.正则表达式中,re.compile(pattern=pattern, flags=re.S)的第二个参数的使用,模式修正,防止有用信息被过滤掉。
4.函数的构建必须放在函数调用之前。