datawhale任务2-爬取豆瓣top250


正则表达式

正则表达式的功能用于实现字符串的特定模式精确检索或替换操作。

常用匹配模式

模式 描述
\w 匹配字母、数字及下划线
\W 匹配不是字母、数字或下划线的字符
\s 匹配任意空白字符,等价于[\t\n\r\f]
\S 匹配任意非空白字符
\d 匹配任意数字,等价于[0-9]
\D 匹配任意非数字的字符
\A 匹配字符串开头
\Z 匹配字符串结尾,如果存在换行,只匹配到换行前的结束字符串
\z 匹配字符串结尾,如果存在换行,同时还会匹配换行符
\G 匹配最后匹配完成的位置
\n 匹配一个换行符
\t 匹配一个制表符
^ 匹配一行字符串的开头
$ 匹配一行字符串的结尾
. 匹配任意字符,除了换行符,添加修饰符,可匹配任意字符
[...] 用来表示一组字符,单独列出,比如[amk]则匹配a,m,k
[^...] 不在[]中的字符,比如[^abc],即除了a,b,c之外的字符
* 匹配0个或多个表达式
+ 匹配1个或多个表达式
? 匹配0个或1个前面的正则表达式定义的片段,非贪婪方式
{n} 精确匹配n个前表达式
{n, m} 匹配n到m次由前面正则表达式定义的片段,贪婪方式
a 管道符 b 匹配a或b
() 匹配括号内的表达式,也表示一个组

常用修饰符

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

基本方法

  • match():以表达式开头进行匹配,一旦开头不匹配,整个匹配就会失败,返回None
  • search():扫描整个字符串,返回第一个成功匹配的字符中,否则返回None
  • findall():搜索整个字符串,返回匹配成功的所有字符串,否则返回空列表

豆瓣250页面分析

豆瓣Top250是包含250部电影,此次爬取的数据为之250部电影的排名,电影名,导演及国家。

url为:https://movie.douban.com/top250?start=0,默认每页有25部电影信息。

每往后翻一页,url中start参数每次即增加25,即250部电影,10页。

豆瓣有反爬虫,如果过多请求会被封,所以先建立一个文件夹用于存储以爬取的网页,如果下次爬取本地有相应的文件,就不会发起网络请求,从而节省下时间,也不会吸引豆瓣反爬系统的注意。

    if 'cached' not in os.listdir('./'):
os.system('mkdir cached')
listdir = os.listdir("./cached")
path = './cached/'
def download(index, url, listdir, path):
# 下标,目标网址,已缓存的文件,文件保存路径
target_file = "{}.html".format(index)
target_url = url.format(index * 25)
if target_file not in listdir:
# 对应的 html 没有下载下来
html = requests.get(target_url, headers=headers)
html.encoding = 'utf-8'
with open(path + target_file, 'w+') as file:
file.write(html.text)
html = html.text
else:
with open(path + target_file, 'r') as file:
html = file.read()
return html

要爬取的信息是排名,电影名,导演,国家

排名在字符串的位置如下

通过浏览器的开发者面板看到是这样的

实际是这样的

电影名位于<span class='title'>XXX</span>中,其中有些有两个<span class='title'>,为避免数据混乱,故只采用一个第一个title,且导演名在信息中的相对位置是肯定的且每部电影都有导演的相关信息,在<p class=""></p>中,故将三都的信息均写于一个正则表达式

three_pattern = re.compile(('<em class="">(.*?)</em>.*?<span class="title">(.*?)</span>'
'.*?<p class="">.*?导演:(.*?)&nbsp;'), re.S)

刚开始时原是把国家的正则匹配也写在一起,后来发现那样会导致有些数据无法匹配,所以分开写,如下

nation_pattern = re.compile('<br>.*?/&nbsp;(.*?)&nbsp;/.*?</p>', re.S)

完整代码

"""
datawhale爬虫任务2
任务:爬取豆瓣电影250
分析 URL,有一个GET参数,start每次变化增加250
https://movie.douban.com/top250?start=0
鉴于豆瓣电影会反爬虫,故将内容先爬下本地,再分析
"""
import requests
import os
import re # (提取名次,片名,导演),(国家)
three_pattern = re.compile(('<em class="">(.*?)</em>.*?<span class="title">(.*?)</span>'
'.*?<p class="">.*?导演:(.*?)&nbsp;'), re.S)
nation_pattern = re.compile('<br>.*?/&nbsp;(.*?)&nbsp;/.*?</p>', re.S) headers = {
'User-Agent': ('Mozilla/5.0 (X11; Linux x86_64)'
' AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/68.0.3440.106 Safari/537.36')
} class Movie(object):
def __init__(self, rnd, n):
# rnd: 名次,名字,导演
# n: 国家
self.info = {
'排名': rnd[0],
'电影名': rnd[1],
'导演': rnd[2],
'国家': n
} def __repr__(self):
return str(self.info) def download(index, url, listdir, path):
# 下标,目标网址,已缓存的文件,文件保存路径
target_file = "{}.html".format(index)
target_url = url.format(index * 25)
if target_file not in listdir:
# 对应的 html 没有下载下来
html = requests.get(target_url, headers=headers)
html.encoding = 'utf-8'
with open(path + target_file, 'w+') as file:
file.write(html.text)
html = html.text
else:
with open(path + target_file, 'r') as file:
html = file.read()
return html def parse(html):
# 分析面页面,提取数据
# 名次,影片名称,导演
rank_name_dire = re.findall(three_pattern, html)
# 国家
nation = re.findall(nation_pattern, html)
info = [Movie(i[0], i[1]) for i in zip(rank_name_dire, nation)]
for i in info:
print(i) def main():
if 'cached' not in os.listdir('./'):
os.system('mkdir cached')
listdir = os.listdir("./cached")
path = './cached/'
url = 'https://movie.douban.com/top250?start={}'
for i in range(10):
html = download(i, url, listdir, path)
parse(html)
print("结束") if __name__ == '__main__':
main()

参考资料

正则表达式和豆瓣Top250的爬取练习的更多相关文章

  1. 豆瓣电影信息爬取(json)

    豆瓣电影信息爬取(json) # a = "hello world" # 字符串数据类型# b = {"name":"python"} # ...

  2. Python爬虫入门教程:豆瓣Top电影爬取

        基本开发环境 Python 3.6 Pycharm 相关模块的使用 requests parsel csv 安装Python并添加到环境变量,pip安装需要的相关模块即可. 爬虫基本思路 一. ...

  3. 艺恩网内地总票房排名Top100信息及其豆瓣评分详情爬取

    前两天用python2写的一个小爬虫 主要实现了从http://www.cbooo.cn/Alltimedomestic这么个网页中爬取每一部电影的票房信息等,以及在豆瓣上该电影的评分信息 代码如下 ...

  4. python 豆瓣图片的爬取

    豆瓣图片的抓取:在python中实现生产者和消费者模型的实现,大家可以参考这篇文章 http://www.bkjia.com/Pythonjc/978391.html 个人认为是讲的比较易懂的,只要看 ...

  5. 豆瓣读书top250数据爬取与可视化

    爬虫–scrapy 题目:根据豆瓣读书top250,根据出版社对书籍数量分类,绘制饼图 搭建环境 import scrapy import numpy as np import pandas as p ...

  6. Scrapy教程--豆瓣电影图片爬取

    一.先上效果 二.安装Scrapy和使用 官方网址:https://scrapy.org/. 安装命令:pip install Scrapy 安装完成,使用默认模板新建一个项目,命令:scrapy s ...

  7. 豆瓣网post 爬取带验证码

    # -*- coding: utf- -*- import scrapy import requests from ..bao.jiema import get_number fromdata = { ...

  8. 正则表达式_爬取豆瓣电影排行Top250

    前言: 利用简单的正则表达式,获取响应内容爬取数据. Part1 正则表达式(Regular Expression) 1.1 简介 正则表达式,又称规则表达式,它是一种文本模式,就是通过事先定义好的一 ...

  9. python爬取豆瓣前25个影片内容的正则表达式练习

    通过python正则表达式获取豆瓣top250的第一页的25个影片排名,影片名字,影片连接,导演,主演,上映日期,国家,剧情,评分,评价人数的内容 网页html内容: <ol class=&qu ...

随机推荐

  1. BZOJ 1455 罗马游戏 左偏树

    题目大意:给定n个点,每一个点有一个权值,提供两种操作: 1.将两个点所在集合合并 2.将一个点所在集合的最小的点删除并输出权值 非常裸的可并堆 n<=100W 启示式合并不用想了 左偏树就是快 ...

  2. Linux下的五种I/O模型

    堵塞I/O(blocking I/O) 非堵塞I/O (nonblocking I/O) I/O复用(select 和poll) (I/O multiplexing) 信号驱动I/O (signal ...

  3. 125条常见的java面试、笔试题大汇总

    1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解所有问题,而仅仅是选择当中的一部分,临时不用部分细节.抽象包含两个方面,一是过程抽象. ...

  4. 利用LruCache载入网络图片实现图片瀑布流效果(改进版)

    PS: 2015年1月20日21:37:27 关于LoadImageAsyncTask和checkAllImageViewVisibility可能有点小bug 改动后的代码请參见升级版本号的代码 ht ...

  5. 现代英特尔® 架构上的 TensorFlow* 优化——正如去年参加Intel AI会议一样,Intel自己提供了对接自己AI CPU优化版本的Tensorflow,下载链接见后,同时可以基于谷歌官方的tf版本直接编译生成安装包

    现代英特尔® 架构上的 TensorFlow* 优化 转自:https://software.intel.com/zh-cn/articles/tensorflow-optimizations-on- ...

  6. JavaScript:DOM对象

    ylbtech-JavaScript:DOM对象 1. HTML DOM Document 对象返回顶部 1. HTML DOM Document 对象 HTML DOM 节点 在 HTML DOM ...

  7. 09.ws复杂数据类型数据传输

    和ajax的共同点是都是自己组装消息自己解析消息.这种方式的好处是一点都不用生成客户端代码.这两种方式(ajax和HttpUrlConnection)的好处是一点都不用生成客户端代码. WSDL这个文 ...

  8. 21. Merge Two Sorted Lists[E]合并两个有序链表

    题目 Merge two sorted linked lists and return it as a new list. The new list should be made by splicin ...

  9. BPM不同表单之间子表的赋值

    上次写的是同一个表单的子表之间赋值,这次是不同表单之间子表的赋值 首先,我们给需要赋值的表单添加一个复制按钮 $.MvcSheet.AddAction({            Action: &qu ...

  10. B - Nearly Lucky Number

    Problem description Petya loves lucky numbers. We all know that lucky numbers are the positive integ ...