首页 » Web前端 » php大夫源码技巧_Python爬取豆瓣片子中国年夜夫爬虫之路永无止境附源码

php大夫源码技巧_Python爬取豆瓣片子中国年夜夫爬虫之路永无止境附源码

访客 2024-11-24 0

扫一扫用手机浏览

文章目录 [+]

今日目标:爬取豆瓣电影中国年夜夫评论实现数据可视化

序言

前段韶光,主旋律电影《中国年夜夫》上线,大家有没有去看呢?反正我去看了,有点动听(实在哭得稀里哗啦)。
看完后,内心感概万分,回到家缓了好久。
看了电影的海报画面,想着可以爬一爬大家对电影的评论,恰好给大家写文了。
于是,利用放工韶光给大家做了这个爬虫项目。
废话不多了,直接开整。

php大夫源码技巧_Python爬取豆瓣片子中国年夜夫爬虫之路永无止境附源码

工具利用

开拓环境

php大夫源码技巧_Python爬取豆瓣片子中国年夜夫爬虫之路永无止境附源码
(图片来自网络侵删)

系统:Windows10 64位

Python版本:Python3.7

IDE:Pycharm

第三方库:selenium lxml re wordcloud PIL numpy jieba matplotlib

代码演示

饼图

饼图

词云天生

词云天生

柱状图天生

柱状图天生

项目思路剖析

1 获取网址规律

可以看到 start 和 status是变革的关键

在这个页面可以通过xpath获取地址网页 评论详情 和评分

地址网页:

评论详情:

评分 :

2 打开地址网页,获取地址信息

有些没有地址信息 所有须要获取全部 后期通过数据处理获取有地址信息的

3 把获取的数据进行解析 分别存放三个文件

4 通过读取相应的文件天生相应的图表

项目难点剖析

1 滑块验证

这个参考代码里面的滑块验证的方法

通过像素比拟找到缺口

移动一段间隔 之后速率变革逐步往前面走 到达缺口就能够验证成功

2 切换iframe

# 切换iframedriver.switch_to.frame(1)

须要切换iframe才能找到滑块和输入账号 密码 的元素位置

3 显示等待

wait.until(EC.presence_of_element_located((By.XPATH, '//[@id="profile"]/div/div[2]')))

等待元素涌现才进行下一步的处理

4 数据处理

涌现不合法的数据 比如 该用户已经主动注销帐号

判断源代码中是否存在 如果存在就跳过 防止等待韶光过长 退出程序

if driver.page_source.__contains__("`该用户已经主动注销帐号`"):continue

5 抓取思维

采纳先抓大再抓小

这样可以确定几个元素是相对应的

循环的时候会再次利用xpath 此时的xpath写法

须要加一个 .

item = {"href": email_detail.xpath('./div/a/@href'),"detail": email_detail.xpath("./div[2]/p/span//text()"),"rate": email_detail.xpath("./div[2]/h3/span[2]/span[2]/@class")}

6 json模块默认编码

默认:ascii码 为了中文的精确显示 须要通报参数ensure_ascii

f.write(json.dumps(email, ensure_ascii=False) + ",\n")

7 词云图的天生

按照图片格式只须要添加一个参数即可mask

# graph 图片工具word_cloud = WordCloud(font_path="simsun.ttc",background_color="white",mask=graph, # 指定词云的形状)

8 柱状图和饼图

难点在于json文件读取

循环获取的data 然后通过列表构建echarts须要的数据格式

$.getJSON("json_file/rate.json", function(data) {var x_data = [];for (var i = 0; i < data.length; i++) {console.log(data[i]);for(var key in data[i]){ // 输出字典元素,如果字典的key是数字,输出时会自动按序输出hello = {value: data[i][key], name: key+"星"}x_data[i] = hello;}};源码展示

词云图

# 词云天生import jiebaimport numpy as npfrom wordcloud import WordCloudimport matplotlib.pyplot as pltfrom PIL import Imagetext = open("json_file/detail.text",encoding='utf8').read()text = text.replace('\n',"").replace("\u3000","")text_cut = jieba.lcut(text)text_cut = ' '.join(text_cut)# 紧张差异background = Image.open("image/mmexport1626868510673.jpg")graph = np.array(background)word_cloud = WordCloud(font_path="simsun.ttc", background_color="white", mask=graph, # 指定词云的形状 )word_cloud.generate(text_cut)plt.subplots(figsize=(12,8))plt.imshow(word_cloud)plt.axis("off")plt.show()

滑块验证

def slide(driver): """滑动验证码""" # 切换iframe driver.switch_to.frame(1) # 找到滑块 block = driver.find_element_by_xpath('//[@id="tcaptcha_drag_button"]') # 找到刷新 reload = driver.find_element_by_xpath('//[@id="reload"]') while True: # 摁下滑块 ActionChains(driver).click_and_hold(block).perform() # 移动 ActionChains(driver).move_by_offset(180, 0).perform() # 获取位移 tracks = get_tracks(30) # 循环 for track in tracks: # 移动 ActionChains(driver).move_by_offset(track, 0).perform() # 开释 ActionChains(driver).release().perform() # 停一下 time.sleep(2) # 判断 if driver.title == "登录豆瓣": print("失落败...再来一次...") # 单击刷新按钮刷新 reload.click() # 停一下 time.sleep(2) else: break

打开文件获取洗濯数据

def get_file(): # 打开文件获取洗濯数据 f = open('data.json', 'r', encoding="utf-8") hello = f.read() # 地址列表 评分列表 评论内容列表 address_ = [] rate_ = [] detail_ = [] # 按换行符进行 for i in hello.split("\n"): try: # 转换为字典 data = eval(i[:len(i) - 1]) # 获取评论详细内容 detail = data.get("detail")[0] # 获取评分 rate = re.findall("(\d{1})\d", data.get("rate")[0])[0] # 获取地址 address = ".".join(re.findall("常居:([\u4e00-\u9fa5]{2})", "".join(data.get("address")))) # 地址存在则添加到地址列表中 if address: address_.append(address) # 把评分添加到评分列表中 rate_.append(rate) # 把评论添加到评论列表中 detail_.append(detail) except: continue

获取评分和唯一地址

# 获取评分和地址的唯一 rate_set = set(rate_) address_set = set(address_) # 写入 评分json with open("json_file/rate.json", 'w', encoding="utf-8") as file: rate_json_list = [] for r in rate_set: # 获取评分频次并且布局字典 rate_json = {r: rate_.count(r)} rate_json_list.append(rate_json) file.write(json.dumps(rate_json_list, ensure_ascii=False))

写入地址json文件

# 写入地址json文件 with open("json_file/address.json", 'w', encoding="utf-8") as file: address_json_list = [] for a in address_set: # 获取地址频次并且布局字典 address_json = {a: address_.count(a)} address_json_list.append(address_json) file.write(json.dumps(address_json_list, ensure_ascii=False))

写入详情文件夹

# 写入详情文件夹 with open("json_file/detail.text", 'w', encoding="utf-8") as file: detail = "".join(detail_).replace("\n", "") file.write(detail)def get_json(data, driver, f): Html = etree.HTML(data) # 通过xpath获取相应的板块 email_details = Html.xpath('//[@id="comments"]/div') items = [] # 循环板块 获取每一个板块里面的数据 for email_detail in email_details: # 地址页的地址 评论内容 评分呢 item = { "href": email_detail.xpath('./div/a/@href'), "detail": email_detail.xpath("./div[2]/p/span//text()"), "rate": email_detail.xpath("./div[2]/h3/span[2]/span[2]/@class") } items.append(item)

循环列表获取地址网址

# 循环列表获取地址网址 爬取地址 for email in items: # 如果网址为控则跳过 if not email.get("href"): continue driver.get(email.get("href")[0]) # 如果评论用户已经注册则跳过 if driver.page_source.__contains__("该用户已经主动注销帐号"): continue print(email.get("href")) wait = WebDriverWait(driver, 10) # 隐士等待 等待数据板块涌现进行下一步 wait.until( EC.presence_of_element_located((By.XPATH, '//[@id="profile"]/div/div[2]')) ) # 获取地址 email["address"] = etree.HTML(driver.page_source).xpath('//[@id="profile"]/div/div[2]/div[1]/div//text()') # 整体数据写入初始文件中 f.write(json.dumps(email, ensure_ascii=False) + ",\n")

主程序

def main(user, pwd): """主程序""" f = open("data.json", "w", encoding="utf-8") f.write("[") url = "https://accounts.douban.com/passport/login" # 驱动路径 driver_file = os.path.join(os.path.dirname(__file__), "driver_exe", "chromedriver.exe") # 声明驱动 driver = webdriver.Chrome(executable_path=driver_file) driver.get(url) driver.find_element_by_xpath('//[@id="account"]/div[2]/div[2]/div/div[1]/ul[1]/li[2]').click() driver.find_element_by_xpath('//[@id="username"]').send_keys(user) driver.find_element_by_xpath('//[@id="password"]').send_keys(pwd) driver.find_element_by_xpath('//[@id="account"]/div[2]/div[2]/div/div[2]/div[1]/div[4]/a').click() # 停一下,等待涌现 time.sleep(2) # 滑动验证码 slide(driver) print("成功") type_mile = ["P", "F"] for type_ in type_mile: if type_mile == "P": index_mile = 480 else: index_mile = 180 for i in range(0, index_mile, 20): url = f"https://movie.douban.com/subject/35087699/comments?start={i}&limit=20&status={type_}&sort=new_score" print(url) driver.get(url) # 解析数据 get_json(driver.page_source, driver, f) f.write("]") driver.quit() get_file() # 所有数据获取完毕之后推出浏览器 解析数据 # 解析完毕并且创建解析之后数据的json文件 f.close()if __name__ == '__main__': user = input("请输入你的账号:") pwd = input("请输入你的密码:") main(user, pwd)

仅供学习,爬虫利用需谨慎!

希望可以得到各位的一键三连,感谢各位支持!

祝大家学习python顺利!

如果有正在跟我一样的自学的朋友,须要我本篇的代码或者其他的Python学习资料可以转发此文私信我(私信发我“中国年夜夫”)

标签:

相关文章

今日头条算法如何实现个化推荐与精准传播

信息传播方式发生了翻天覆地的变化。今日头条作为国内领先的信息分发平台,凭借其强大的算法推荐系统,吸引了海量用户。今日头条的算法究竟...

Web前端 2025-01-31 阅读1 评论0

今日头条算法关闭之谜内容分发新格局

今日头条作为一款备受瞩目的新闻资讯平台,凭借其独特的算法推荐机制,吸引了大量用户。近期有关今日头条算法关闭的消息引发了广泛关注。本...

Web前端 2025-01-31 阅读1 评论0

今日头条算法智能推荐背后的科技魅力

信息爆炸的时代已经到来。人们每天在互联网上接触到海量的信息,如何从中筛选出有价值的内容,成为了人们关注的焦点。今日头条作为一款智能...

Web前端 2025-01-31 阅读1 评论0

今日头条算法专利申请个化推荐的秘密武器

信息爆炸的时代已经来临。在众多信息中,如何快速找到自己感兴趣的内容成为了一个难题。今日头条作为中国领先的资讯平台,凭借其独特的算法...

Web前端 2025-01-31 阅读1 评论0

今日头条算法机器推荐模式的秘密与挑战

大数据、人工智能等新兴技术的应用已经渗透到我们生活的方方面面。在信息爆炸的时代,人们获取信息的渠道越来越丰富,如何在海量信息中找到...

Web前端 2025-01-31 阅读1 评论0