一、使用正则表达
对于正则表达式这种用起来像毒药的东西,一旦用上手就不想放手,但是经常会遗忘。想要做到不遗忘,最好的方法当然是自己造个轮子把正则表达式实现出来(手动滑稽。
介绍一下常用的几种符号:
* | 匹配前面的字符、子表达式或括号里的字符。可以是0次或多次 |
| | 匹配任意一个由竖线分割的字符、子表达式 |
$ | 用在正则表达式的末尾,表示“从字符串的末端匹配”。如果不用它,每个正则表达式实际都带着” .* “模式,只会从字符串开头进行匹配。这个符号可以看成是^符号的反义词 |
?! | “不包含”。这个组合通常放在字符或正则表达式前面,表示字符不能出现在目标字符串里。这个字符比较难用,字符通常会在字符串的不容部位出现。如果要在整个字符串中全部排除某个字符,就要加上^和$符号 |
^ | 指从字符串开始位置的字符或子表达式 |
. | 匹配单个任意字符(包括符号、数字和空格等) |
{m, n} | 匹配前面的字符、子表达式或括号里的字符m到n次(包括m或n) |
二、调用Python的re模块,配合使用正则表达式
在这里,我以豆瓣为例,爬取豆瓣里的链接。https://movie.douban.com/subject/26887161/?from=showing链接的结构大致如此,写了一个小小的正则表达式以匹配包含showing的链接
from urllib.request import urlopen
from bs4 import BeautifulSoup
import datetime
import random
import re
random.seed(datetime.datetime.now())
def getlinks(url):
html = urlopen("https://movie.douban.com/")
bsObj = BeautifulSoup(html, "html.parser")
_list = bsObj.find("li", class_="ui-slide-item s").findAll("a", href=re.compile(r"[\s\S]*showing"))
for link in _list:
print("############")
if 'href' in link.attrs:
print(link.attrs['href'])
return _list
links = getlinks(None)
i = 0
while len(links) > 0:
i += 1
newUrl = links[random.randint(0, len(links)-1)].attrs['href']
print(newUrl)
links = getlinks(newUrl)
print(i) #输出是第几次递归寻找中
print(i) #只有在新页面中没有链接的情况下这里才能输出