寒假大数据学习笔记六
今天学习了基本的正则表达式,难度的确不小,光这么一天是绝对学不完的,我也只是浅尝辄止。
从网上找了一份关于正则表达式的符号意义:Python3 正则表达式特殊符号及用法(详细列表),很值得参考。其实官方文档上也有,只不过是全英文的:
其实比较常用的正则表达式从网上一搜索就可以得到,但有时候为了某些特定的需求,还是需要自己写一下正则表达式的。
那么说一下有些卡住我的正则表达式:\序号
“\序号”有两种意思:1、0和100以上(包含100)的序号代表8八进制的ASCII值;2、1到99(包括99)表示引用序号对应的子组所匹配的字符串。第一点还算好理解,练习两道题就会了,但第二点真是让我百思不得其解,琢磨可好一阵才理解意思:首先明白的一点是正则表达式中一个小括号就代表一个组,举例:在 (abc)(xyz)\1 中存在两个组,有几组小括号就有几组,现在给这些组表上序号 (abc) 就是1组, (xyz) 就是2组,最后的 \1 就是将第一组重复一遍,也就是说, abcxyzabc 就会匹配成功:
所以同理, (abc)(xyz)\2 可以匹配成功的就是 abcxyzxyz ,当然要注意的一点时,序号不可以超过组数,也就是说不可以写成 (abc)(xyz)\3 ,这样是会报错的:
好了,正则表达式的问题搞定了,那就写程序练习一下吧:由于在使用代理IP时复制IP地址,复制端口太麻烦了,干脆直接从网页爬取IP和端口好了,制作成列表,然后用random随机选用岂不美哉?
首先打开一个提供免费IP代理的网站:国内高匿免费HTTP代理IP - 快代理,查看开发者选项:
哇,真是太贴心了!竟然还有data-title这么明显的元素!接下来的问题就是识别IP地址和端口了,正则表达式如下:
# 识别IP地址的正则表达式 pattern_ip = r'<td data-title="IP">((?:(?:25[0,5]|2[0,4]\d|[0,1]?\d?\d)\.){3}(?:25[0,5]|2[0,4]\d|[0,1]?\d?\d))' # 识别端口的正则表达式 pattern_port = r'<td data-title="PORT">(\d{1,5})'
最难的问题也解决了,附上源码:
from urllib import request from fake_useragent import UserAgent import re import requests import random def url_open(url): # 编写请求头 header = { "User-Agent": UserAgent().random } req = requests.get(url, headers=header) return req.text # 得到IP地址和端口号 def get_IP_port(url): html = url_open(url) # 识别IP地址的正则表达式 pattern_ip = r'<td data-title="IP">((?:(?:25[0,5]|2[0,4]\d|[0,1]?\d?\d)\.){3}(?:25[0,5]|2[0,4]\d|[0,1]?\d?\d))' # 识别端口的正则表达式 pattern_port = r'<td data-title="PORT">(\d{1,5})' iplist = re.findall(pattern_ip, html) portlist = re.findall(pattern_port, html) # 将IP地址和端口合并 proxylist = [iplist[i] + ":" + portlist[i] for i in range(len(iplist))] # print(proxylist) return portlist if __name__ == '__main__': get_IP_port("https://www.kuaidaili.com/free/inha/21/")