Skip to content

Latest commit

 

History

History
111 lines (77 loc) · 4.69 KB

实验报告.md

File metadata and controls

111 lines (77 loc) · 4.69 KB

数据分析及实践 实验报告

实验二 数据获取与管理


实验目的

豆瓣网站https://movie.douban.com的电影详细信息爬取


实验内容与结果

实验环境

  • python 3.9.7
  • python module: random, bs4, re, urllib, json, time, requests, fake_useragent, os
  • Neo4j云数据库:Neo4j Aura

Part1 电影详细信息爬取

  1. 搜索策略

    一个简单的搜索策略是爬取豆瓣的前250评分电影,这里我希望探索不一样的搜索策略:对电影的推荐进行深度搜索。豆瓣对每部电影都会进行一个相关推荐,即“喜欢这部电影的人也喜欢”栏目,其中会推荐十部电影,如图。通过这个推荐,我们可以从任意一部电影出发,进行一个深度优先搜索,不断获取相关电影的信息。一个需要注意的问题是,爬取过程中,新的电影可能推荐已经搜索过的电影。我发现豆瓣对每个电影有一个唯一编号,在URL看到:https://movie.douban.com/subject/1292064/,编号为1292064,则根据编号对已搜索电影建立列表即可避免重复搜索。

    ![](D:\data analysis and pratice\results\report_pic1.png)

  2. 网页获取

    起先使用 urllib 库进行网页获取,由于后续实验中出现被封IP的问题,转用 requests 库,使用 session() 对象进行爬取,同时使用 fake_useragent 库的 UserAgent() 函数随机产生UA,用time.sleep(2*random())产生随机延迟。

    # urllib库获取网页内容
    def askURL(url):
        head = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \
                 Chrome/99.0.4844.51 Safari/537.36"
        }
    
        req = urllib.request.Request(url, headers=head)
        html = ""
        try:
            response = urllib.request.urlopen(req)
            html = response.read().decode("utf-8")
            #print(html)
        except urllib.error.URLError as e:
            if hasattr(e,"code"):
                print(e.code)
            if hasattr(e,"reason"):
                print(e.reason)
        response.close()
        return html
    if __name__ =="__main__":
        #*********code*********
    	sess = requests.session()
    	#*********code*********
    # requests库获取网页内容
    def askURL2(url):
        head = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \
                 Chrome/99.0.4844.51 Safari/537.36"
        }
        fake_headers = {"User-Agent":UserAgent().random}
        response = sess.get(url=url, headers=fake_headers)
        return response.content
  3. 网页解析

    使用 bs4 库的 BeautifulSoup 进行网页处理,用 re 库进行正则匹配,获得目标信息。如正则表达式findLink=re.compile(r'<a href="(.*)">')用来获取推荐电影的链接。

  4. 推荐关系存储

    使用Neo4j图数据库线上版本Neo4j Aura对搜索路径和推荐关系进行存储。Neo4j提供了云数据库Neo4j Aura及其python支持库neo4j,对电影建立节点并对推荐建立关系可以得到图数据。这里我采集了两张图,搜索路径图(不含重复推荐,无环)和推荐关系图(含重复推荐),如下。可以发现,电影间存在很强的互推荐关系,事实上我从《楚门的世界》进行了深度为8的搜索,理论上一棵满10叉树有10^7^+个节点,而实际搜索只得到173部电影。而与之相比,从《千与千寻》开始的搜索结果甚至更少,只有91部,我认为原因很可能是动漫电影之间的互推荐关系更强,导致集合更趋近于封闭。

    在main中修改mode变量为'tree'/'map'进行生成图的选择。

    • 搜索路径图![tree](D:\data analysis and pratice\results\tree.svg)

    • 推荐关系图![map](D:\data analysis and pratice\results\map.svg)

Part2 爬取电影对应图片

电影封面图片的爬取是在原来基础上使用正则式获得图片URL,然后进行下载即可。

# 电影封面保存
def saveCover(url,name):
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \
             Chrome/99.0.4844.51 Safari/537.36"
    }
    fake_headers = {"User-Agent":UserAgent().random}
    with open(name, 'wb') as f:
        f.write(sess.get(url=url, headers=fake_headers).content)

结果

爬取电影信息存储在result.json文件中,电影图片存储在covers文件夹中。由于每次爬取会清空之前的结果,我将一份完整的结果放在results文件夹中,直接打开查看即可。