python3正则表达式学习及使用记录

2017.12.23

发现房天下论坛版面改版了,之前用的beautifulsoup写的,发现改动很大,这也说明了BS4基于树结构的查询方式的不便之处,页面结构一旦修改,就很难做到代码重用,于是将抓取论坛的函数中beautifulsoup全部换掉了,换成了正则。

(注释部分是beautifulsoup的方式,其中还有navigable类型转换问题没有解决,不可直接运行;未注释的部分是正则表达式的方式,可直接运行。)

            
def get_luntan(url,headers):
    lt_name = []
    lt_url = []
    article_count = []
    res = requests.get(url,headers = headers)
    '''
    soup = BeautifulSoup(res.text,'lxml',from_encoding='utf-8')
    lt_list_left = soup.select('body .articleAre2 .box48L .box13Menu2')[0]
    lt_list_right = soup.select('body .articleAre2 .box48R .box13Menu2')[0]
    #lt_lists = (lt_list_left,lt_list_right)
    #逐个爬取论坛
    #for lt_list in lt_lists:
    for lt in lt_list_left:
        tags = lt.select('.box48MenuR .box48ListRL a')
        lt_name.append(str(tags[0].string))
        lt_url.append(tags[0]['href'])
        article_count.append(str(lt.select('.box48MenuR .box48ListRR3 .s1')[2].string))
    for lt in lt_list_right:
        tags = lt.select('.box48MenuR .box48ListRL a')
        lt_name.append(str(tags[0].string))
        lt_url.append(tags[0]['href'])
        article_count.append(str(lt.select('.box48MenuR .box48ListRR3 .s1')[2].string))
    '''
    a_list = re.compile('<div class="box48ListRL">(.*?)</div>').findall(res.text)
    a_range = [i for i in range(0,150) if (i%100<50 and i%100>=0)]
    for i in a_range:
        lt_name.append(re.search('target="_blank">(.*?)</a>',a_list[i],re.M|re.I)[1])
        lt_url.append(re.search('href=\'(.*?)\'',a_list[i],re.M|re.I)[1])
    #将论坛地址存入数据库
    for i in range(len(lt_name)):
        sql = 'insert into luntan(lt_name,lt_url,article_count) values (%s,%s,%s)'
        sql_params = (lt_name[i],lt_url[i],article_count[i])
        saveDB(sql,sql_params)
    print(len(lt_url))


之前一直用re.compile().findall(),今天发现re.compile.find()是不存在的,如果想只选择一个结果,re.search(pattern,
string, flags=0),这样得到的是第一个匹配的结果,flags是一些筛选条件设定:(常用的是re.I | re.M

正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符描述
re.I使匹配对大小写不敏感
re.L做本地化识别(locale-aware)匹配
re.M多行匹配,影响 ^ 和 $
re.S使 . 匹配包括换行在内的所有字符
re.U根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

另外,在使用search方法的时候,发现,以前使用compile函数的findall()时可以用[0]获取(.*?)中的值,但是search函数用[0]获得的是匹配的全部字符串,而不是(.*?)中的字符串,想要得到(.*?)中的字符串需要用[1],也就是说,我理解的是,compile函数是从0开始得到选定字符串的,而search函数是从1开始得到选定字符串的。

另外,当‘’“”在(.*?)紧邻时,必须转义,否则就会将(.*?)当做字符串而不是匹配符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值