#使用requests库爬取猫眼电影排行榜
# encoding=utf-8
import re
import requests
import json
from requests.exceptions import RequestException
def get_open_page(url):
try:
# 请求头 添加user-agent用于伪装浏览器
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
}
#使用localhost作为代理服务器
proxies ={
'http': 'http://127.0.0.1'
}
reponse = requests.get(url,headers=headers,timeout=3,proxies=proxies)
# 设置编码 不设置可能出现乱码
reponse.encoding = 'utf-8'
if reponse.status_code == 200:
return reponse.text
return None
except RequestException:
return None
def main():
# 爬取排名前100的电影
for i in range(0,10):
url = 'https://maoyan.com/board/4?offset=';
url = url + str(i*10)
html = get_open_page(url)
# 使用正则表达式筛选
pattern = re.compile('.*?board-index.*?>(.*?).*?name.*?a.*?>(.*?).*?star.*?>\s+(.*?)\s+.*?.*?releasetime.*?>(.*?).*?integer.*?>(.*?).*?fraction.*?>(.*?).*?',re.S)
result = re.findall(pattern, html)
dic = {}
for items in result:
dic = {
'top:': items[0],
'name:': items[1],
'stars:': items[2],
'releasetime:': items[3],
'score':items[4]+items[5]
}
print (dic)
main()
补充:有关python中正则表达式的部分用法
常规的匹配规则
模式 描述
\w 匹配字母、数字及下划线
\W 匹配不是字母、数字及下划线的字符
\s 匹配任意空白字符,等价于[\t\n\r\f]
\S 匹配任意非空字符
\d 匹配任意数字,等价于[0-9]
\D 匹配任意非数字的字符
\A 匹配字符串开头
\Z 匹配字符串结尾,如果存在换行,只匹配到换行前的结束字符串
\z 匹配字符串结尾,如果存在换行,同时还会匹配换行符
\G 匹配最后匹配完成的位置
\n 匹配一个换行符
\t 匹配一个制表符
^ 匹配一行字符串的开头
$ 匹配一行字符串的结尾
. 匹配任意字符,除换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
[...] 用来表示一组字符,单独列出,比如[amk]匹配a、m或k
[^...] 不在[]中的字符,比如[^abc]匹配除a、b、c以外的任意字符
* 匹配0个或者多个表达式
+ 匹配1个或者多个表达式
? 匹配0个或者1个前面的正则表达式定义片段,非贪婪方式
{n} 精确匹配n个前面的表达式
{n,m} 匹配n到m次由前面正则表达式定义的片段,贪婪方式
a|b 匹配a或者b
() 匹配括号内的表达式,也表示一个组
match(),向它传入要匹配的字符串以及正则表达式,就可以检测这个正则表达式是否匹配字符串。
import re
content = 'Hello 123 4567 World_this is a Regex Demo'
print(len(content))
result = re.match('Hello\s\d\d\d\s\d{4}\s\w{10}',content)
print result
print (result.group())
findall(),搜索整个字符串,然后返回正则表达式中所有匹配的内容。
compile(),将正则字符串编译为正则表达式对象,以便后面匹配中复用。
贪婪与非贪婪
# 贪婪方式
import re
content = 'Hello 1234567 World_this is a Regex Demo'
result = re.match('^He.*(\d+).*Demo$',content)
print(result.group(1))
# 输出的结果为7,在贪婪匹配下,.*会匹配尽可能多的字符。He后面的.*将123456匹配了,给\d+留下的只有7。所以我们需要用非贪婪方式。非贪婪方式匹配的写法为.*?
# 非贪婪方式
import re
content = 'Hello 1234567 World_this is a Regex Demo'
result = re.match('^He.*?(\d+).*?Demo$',content)
print(result.group(1))
# 输出的结果为1234567
实例:
就拿上面爬虫的正则表达式为例。
网页源代码:
2019-01-09已更新
榜单规则:将猫眼电影库中的经典影片,按照评分和评分人数从高到低综合排序取前100名,每天上午10点更新。相关数据来源于“猫眼电影库”。
-
1
霸王别姬
主演:杨永超,宋小川,张进战
上映时间:1993-01-01
-
2
肖申克的救赎
主演:乔·劳格诺,斯科特·曼,约翰·霍顿
上映时间:1994-10-14(美国)
-
正则表达式:pattern = ‘
- .*?board-index.*?>(.*?).*?name.*?a.*?>(.*?).*?star.*?>\s+(.*?)\s+.*?.*?releasetime.*?>(.*?).*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
’
我们所需要的内容都放在(.*?)中。
每个影片的名字,主演等信息都写在一个
- 标签中。
所以正则表达式开头为
- ,由
- 到border-index之间没有我们需要的内容所以使用.*?匹配
排名前面有个标志:border-index,我们需要将其写入正则表达式中,告诉系统我们已经匹配到1处了,由于border-index后面还有一部分我们不需要的内容,所以还要使用.*?进行匹配。到>1时,我们需要在正则表达式中加入>,告诉系统下面将要匹配到我们需要的内容,需要的内容用(.*? ),然后再加上告诉系统我们所需要匹配的内容在处结束。后面的写法与此类似,就不一一进行讲解。
通过使用pattern1=re.compile(pattern)编译为正则表达式对象,再使用re.findall(pattern1,text);(text为所需匹配的内容)findall方法会将所匹配的内容生成元组。直接输出元组就可以得到我们需要的内容。