爬虫(三)lxml+requests(豆瓣Top250电影)

news/2024/7/19 8:46:49 标签: lxml, requests, 爬虫, 豆瓣, json

回家之后就不想学习了…

这次用的是lxml库,因为听说比起BeautifulSoup它的速度更快,然后就想了解一下。(全部的代码在最下面)

import库
from lxml import etree
import requests
import json
# from time import sleep

这是要用到的库。requests请求html,lxml解析html文档,然后得到的数据通过json存储在json文件。

豆瓣网页">分析豆瓣网页

第一页:https://movie.douban.com/top250
第二页:https://movie.douban.com/top250?start=25&filter=
第三页:https://movie.douban.com/top250?start=50&filter=

发现一页有25个电影介绍,每多一页start=的数目迁移25。因此尝试:

https://movie.douban.com/top250?start=0

发现成功后,分析网页源代码。
这次抓取的只是电影名、排名、分数、和简介。还是跟之前那样子通过Chrome的审查元素抓取Xpath路径。
分别有:

# info
# //*[@id="content"]/div/div[1]/ol/li[1]/div/div[1]/em index
# //*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1] name
# //*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[2] rate
# //*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[2]/p[2]/span quote

这是第一个电影的信息,可以看出来我们要抓取的内容都在一个统一的节点div上。而每个电影都在不同的li里面。

重点代码
def get_one_page(url):
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.content
        return None
    except requests.RequestException:
        return None

这是通过request来请求一个页面的函数。使用的RequestExceptionrequest库自带的,代表连接出错。status_code等于200时代表连接正常,这时候我们返回页面。
更多状态码可以上菜鸟:http://www.runoob.com/http/http-status-codes.html

def parse_one_page(content):
    html = etree.HTML(content)
    films = html.xpath('//div[@class="article"]/ol/li')
    for film in films:
        yield{
            'name': film.xpath('./div//span[@class="title"][1]/text()'),
            'index': film.xpath('./div//div[@class="pic"]/em/text()'),
            'quote': film.xpath('./div//span[@class="inq"]/text()'),
            'rating_num': film.xpath('./div//span[@class="rating_num"]/text()'),
        }

xpath用法中,//表示搜索所有的子孙节点,而/是直接的子节点。我们先通过class属性选择对应的div,再选择它分支的所有li节点。这个时候,我们再迭代所有的li节点。

需要注意的是,我们在迭代的时候只操作当前节点,所以我们路径都有个./

最后选择的是yield,这样子这个函数就是个迭代器了。在主函数中,我们迭代这个函数收集信息就可以了。


def write(data):
    with open('douban_top250.json', 'a', encoding='utf-8') as f:
        f.write(json.dumps(data, ensure_ascii=False) + '\n')

这里把信息写到自己建的文件douban_top250.json中。

if __name__ == '__main__':
    douban_films = 'https://movie.douban.com/top250?start='
    for i in range(0, 226, 25):
        # print(i)
        page = douban_films + str(i)
        content = get_one_page(page)
        if content is not None:
            for item in parse_one_page(content):
                # print(item)
                write(item)
        else:
            print('Request Error')
        # sleep(5)

这个是总的过程。自己设置i遍历25个页面,然后通过自己构造的函数来解析信息,最后输入到文件中。需要解释的是,这里注释掉的三个语句是我在测试的时候检查错误先写上去的。

最终的代码如下(好简短):

from lxml import etree
import requests
import json

def get_one_page(url):
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.content
        return None
    except requests.RequestException:
        return None


def parse_one_page(content):
    html = etree.HTML(content)
    films = html.xpath('//div[@class="article"]/ol/li')
    for film in films:
        yield{
            'name': film.xpath('./div//span[@class="title"][1]/text()'),
            'index': film.xpath('./div//div[@class="pic"]/em/text()'),
            'quote': film.xpath('./div//span[@class="inq"]/text()'),
            'rating_num': film.xpath('./div//span[@class="rating_num"]/text()'),
        }

def write(data):
    with open('douban_top250.json', 'a', encoding='utf-8') as f:
        f.write(json.dumps(data, ensure_ascii=False) + '\n')


if __name__ == '__main__':
    douban_films = 'https://movie.douban.com/top250?start='
    for i in range(0, 226, 25):
        page = douban_films + str(i)
        content = get_one_page(page)
        if content is not None:
            for item in parse_one_page(content):
                write(item)
        else:
            print('Request Error')

效果如图:

这里写图片描述


http://www.niftyadmin.cn/n/1364262.html

相关文章

Spring之ContextLoaderListener

Spring 官方文档 Spring Framework Documentation【Version 5.1.4.RELEASE】 ContextLoaderListener API Doc 介绍 web.xml中配置ContextLoaderListener,可以实例化ApplicationContext You can register an ApplicationContext by using the ContextLoaderListen…

爬虫(四)selenium添加购物车(cookies)

上一篇关于selenium的文章其实只是通过它来得到网页代码,然后用BeautifulSoup来进行信息的查找。 这一次也不复杂,只是通过selenium自带的CSS选择器来选择按钮,然后点击选入购物车。这次模拟的是抢购的场景,也就是设定时间&#…

JDK之Enumeration

源码 package java.util;/*** author Lee Boynton* since JDK1.0*/ public interface Enumeration<E> {boolean hasMoreElements();E nextElement(); }Enumeration的遍历 Spring之ContextCleanupListener源码 package org.springframework.web.context;import java…

html中设置默认的浏览器文档模式

<head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><TITLE>${systemConfig.getStringConfigValue("webtitle")}——登陆</TITLE><meta name"description" content"" /&…

制作简易词典(PyQt5+爬虫)

在查看剑桥词典网页版的时候&#xff0c;逼着自己看英英&#xff0c;但有时候看不懂还得打开英汉的页面。 然后&#xff0c;就自己查了点界面的知识&#xff0c;结合前面学的一点爬虫&#xff0c;捣鼓了一下。 放在这里~~~ 先说明&#xff0c;我也是新手。 from PyQt5.QtWi…

JAVA实现寻找两个有序数组的中位数

介绍 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 请你找出这两个有序数组的中位数&#xff0c;并且要求算法的时间复杂度为 O(m n) 你可以假设 nums1 和 nums2 不会同时为空 源码 public static double getMedianSortedArrays(int[] nums1, int[] nums2) {int lengt…

Pyinstaller闪退补救措施

用Pyinstaller封装一个py文件时&#xff0c;过程没有问题&#xff0c;但打开后会出现闪退的现象。因此上网找&#xff0c;找到了上面网址所示的解决方法。也就是用cmd打开exe文件。 假如我要封装mani.py&#xff0c;Windows下进入文件所在地址&#xff0c;按住shift点击鼠标右…

对移植工程的makefile理解。

本文的目的已在对于makefile结构和其参数的理解。 该工程的编译类型为交叉编译。 工程一共包含5个makefile文件&#xff0c;分别是&#xff1a; ./makefile ./api/compile.cfg ./api/archdef.cfg ./api/rules.cfg ./sudir.cfg 还有一个makefile中的include文件为&#xff1a;./…