Python requests练习:爬取猫眼电影排行

0.前言

本文为《Python3网络爬虫开发实战》的学习笔记。先是跟着书上敲了一遍抓取猫眼排行的代码,但是感觉re正则表达式用起来不大方便,后面自己用PyQuery解析了下。

1.书上的例子(requests+re)

目标地址https://maoyan.com/board/4,top100的排行分为了十页,每个分页只是url增加了一个offset参数,假如要查看top21-30,那么url就是https://maoyan.com/board/4?offset=20,以此类推。通过浏览器查看html内容,每个电影的信息在列表

下的
标签里,每个
节点下面有三个子节点,为前面的标号,包裹该电影图片信息,
包裹该电影具体信息。

对于请求,由于该网站比较简单,直接requests.get就行了,也不需要设置headers什么的。

对于解析,作者使用的正则表达式来匹配字符串,小括号"()"为要提取的子字符串,".*"后面的问号"?"表示非贪婪匹配(点匹配任意字符,星号表示匹配前面的字符无限次),re.S修饰符表示点号可以匹配换行符。

import requests
import re
import json

def get_one_page(url):
    response=requests.get(url)
    if response.status_code == 200:
        return response.text
    return None

def parse_one_page(html):
    pattern = re.compile(
        '
.*?board-index.*?>(.*?).*?data-src="(.*?)".*?name.*?a.*?>(.*?)' +'.*?star.*?>(.*?)

.*?releasetime.*?>(.*?)

.*?integer.*?>(.*?).*?fraction.*?>(.*?).*?
', re.S) items=re.findall(pattern,html) for item in items: yield{ 'index':item[0], 'image':item[1], 'title':item[2].strip(), 'actor':item[3].strip()[3:] if len(item[3])>3 else '', #[:]去掉里面多余的文字信息 'time':item[4].strip()[5:] if len(item[4])>5 else '', 'score':item[5].strip()+item[6].strip() } def write_to_file(content): with open('result.txt','a',encoding='utf-8') as f: f.write(json.dumps(content,ensure_ascii=False)+'\n') if __name__ == "__main__": url='https://maoyan.com/board/4' for i in range(10): html=get_one_page(url+'?offset='+str(i*10)) for item in parse_one_page(html): write_to_file(item)

2.使用PyQuery解析

使用PyQuery的好处就是不用再费心去写正则表达式了,调试也更方便,就是代码貌似更长了。不过选择器匹配出来的字符串信息可能是有无效信息的,这时候还是需要正则表达式来剔除。比如该例子中的主演和时间两项,原字符串是有中文“主演:”和“上映时间:”这样的文字的,作者用的切片来去掉前面固定长度的文字,但是并不完美,因为有些时间后面跟了地区信息,有时候可能想要去掉或者拆分开来,这时候就需要用到正则表达式了。

from pyquery import PyQuery as pq

def parse_one_page(html):
    doc=pq(html)
    items=doc(".board-wrapper dd").items()
    for item in items:
        yield{
            'index':item.find("i.board-index").text(),
            'image':item.find("a img.board-img").attr("data-src"),
            'title':item.find("div .movie-item-info p.name a").attr("title"),
            'actor':item.find("div .movie-item-info p.star").text().strip()[3:],
            'time':item.find("div .movie-item-info p.releasetime").text().strip()[5:],
            'score':item.find("div .movie-item-number p.score").text().strip()
            }

 

你可能感兴趣的:(Python)