专栏名称: dwzb
目录
相关文章推荐
51好读  ›  专栏  ›  dwzb

正则表达式+CSV实战

dwzb  · 掘金  ·  · 2018-04-15 07:34

正文

本文使用正则表达式抓取豆瓣top250电影信息,存储到csv文件中

抓取信息

本文假设读者对正则表达式已经非常熟悉了,如果不熟悉的可以到网上找相关教程。

下面我们抓取豆瓣信息打印出来

import requests
import re
import csv

def parse(text):
    pattern = re.compile('<li>.*?"title">(.*?)<'+
                    '.*?"title">(.*?)<.*?"other">(.*?)<'+
                    '.*?"playable">\[(.*?)\]'+ # 注意方括号要转义
                    '.*?"bd".*?p class="">(.*?)<'+ # 注意class后面有=""
                    '.*?"star".*?rating(.*?)-t'+
                    '.*?"v:average">(.*?)<'+
                    '.*?<span>(\d+)人'+
                    '.*?inq">(.*?)<.*?</li>', re.S)

    for item in re.findall(pattern, text):
        yield {
            'title': item[0],
            'other_title': (item[1].replace('&nbsp;', '') + item[2].replace('&nbsp;', '')).replace(' ', ''),
            'playable': item[3],
            'info': item[4].replace('&nbsp;', '').strip(),
            'star': '.'.join(list(item[5])),
            'score': item[6],
            'comment_num': item[7],
            'quote': item[8]
        }

def get_all():
    for i in range(10):
        url = 'https://movie.douban.com/top250?start={}&filter='.format(i*25)
        text = requests.get(url).text
        yield from parse(text)

def main():
    data = list(get_all())
    print(data)

if __name__ == '__main__':
    main()

使用正则匹配的基本形式是这样的 <>(.*?)</> 。上面只涉及提取,如果提取有困难可以考虑使用 re.sub 删除掉一些干扰字符,再进行提取。

存储CSV

直接上代码

import requests
import re
import csv

def parse(text):
    pattern = re.compile('<li>.*?"title">(.*?)<'+
                    '.*?"title">(.*?)<.*?"other">(.*?)<'+
                    '.*?"playable">\[(.*?)\]'+ # 注意方括号要转义
                    '.*?"bd".*?p class="">(.*?)<'+ # 注意class后面有=""
                    '.*?"star".*?rating(.*?)-t'+
                    '.*?"v:average">(.*?)<'+
                    '.*?<span>(\d+)人'+
                    '.*?inq">(.*?)<.*?</li>', re.S)

    for item in re.findall(pattern, text):
        yield {
            'title': item[0],
            'other_title': (item[1].replace('&nbsp;', '') + item[2].replace('&nbsp;', '')).replace(' ', ''),
            'playable': item[3],
            'info': item[4].replace('&nbsp;', '').strip(),
            'star': '.'.join(list(item[5])),
            'score': item[6],
            'comment_num': item[7],
            'quote': item[8]
        }

def get_all():
    for i in range(10):
        url = 'https://movie.douban.com/top250?start={}&filter='.format(i*25)
        text = requests.get(url).text
        yield from parse(text)

def main():
    data = list(get_all())
    with open('movies.csv', 'w', encoding = 'utf-8') as f:
        w = csv.DictWriter(f, fieldnames = data[0].keys())
        w.writeheader()
        w.writerows(data)

if __name__ == '__main__':
    main()

这里使用 DictWriter 来用字典存入,一般都是用 Write 将列表存入。这里用 writerows 一次存入多个字典,也可以用循环配合 writerow 一条一条写入。







请到「今天看啥」查看全文