python自己摸索:成功动态爬取豆瓣电影Top250名单,并从1-250分别列出来(附最接地气的--详细思路和代码注释)

先说下整体思路:

  1. 找到豆瓣电影Top250的网址 https://movie.douban.com/top250
  2. 确定要爬取的这个html页面是动态页面还是静态页面, 静态页面是可以直接爬取的,动态页面需要从js或者XHR里面去找动态的json数据。 本次爬取的250名单 本质上还是静态的,因为内容都在页面里,我们不需要去js或者xhr里面找数据。
  3. 确认一下 要爬的网页是否有反爬。我们要和反爬 有一个小小的斗争!
  4. 先爬取第一页的电影名单
  5. 利用循环,爬取全部10页里的名单

静态爬取比较简单,主要是思路要对。而且这次爬取是用get请求,就更简单了。

按照上面的思路走,开始代码吧:

第一步: 我们先爬取单个页面来试试水

import requests
from bs4 import BeautifulSoup

url = 'https://movie.douban.com/top250' #url是爬数据的根本,所有流程都是围绕url展开的
# 为了反爬,我们把headers加上
headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        # 'Accept-Encoding': 'gzip, deflate, br', # 这一句代码对编码器有限制,所以注释掉就行了
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive',
        'Cookie': 'douban-fav-remind=1; bid=QhopwFw0HcQ; __utmz=30149280.1586506561.6.5.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; _pk_ses.100001.4cf6=*; __utma=30149280.1613818664.1547469206.1586506561.1594137884.7; __utmb=30149280.0.10.1594137884; __utmc=30149280; __utma=223695111.510808800.1561795806.1561795806.1594137884.2; __utmb=223695111.0.10.1594137884; __utmc=223695111; __utmz=223695111.1594137884.2.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ap_v=0,6.0; _pk_id.100001.4cf6=b46c129b3f0ba258.1561795806.2.1594137900.1561795859.',
        'Host': 'movie.douban.com',
        'Sec-Fetch-Mode': 'navigate',
        'Sec-Fetch-Site': 'none',
        'Sec-Fetch-User': '?1',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
        }
res = requests.get(url, headers=headers) # 发送get请求
    html = res.text # 把请求结果res转换成字符串类型
    soup = BeautifulSoup(html, 'html.parser') # 用html.parser编译html字符串,得到的是列表
    # print(html)
    # print(soup)
    # F12大法,在页面里找一下电影名字所处的位置, 然后右击 → 选COPY → 选copy selector
    # 这里要求要懂一点前端知识啦,ol > li:nth-child(1) > div ... ,意思是选取ol里的第一个li里面的内容
    # 但是我们实际上是要的每个li里面的内容,所以要改一下,改成:ol > li > div > ...
    spans = soup.select('#content > div > div.article > ol > li > div > div.info > div.hd > a > span:nth-child(1)') 
    
    # print(spans)
    # 然后我们对得到的span进行遍历操作,再给电影名前面加上序号
i = 1
for span in spans:
	# print(span)
	print(str(i)+':',  span.text)
	 i += 1

这样,就得到了第一页的输出结果:

1: 肖申克的救赎
2: 霸王别姬
3: 阿甘正传
4: 这个杀手不太冷
5: 美丽人生
6: 泰坦尼克号
7: 千与千寻
8: 辛德勒的名单
9: 盗梦空间
10: 忠犬八公的故事
11: 海上钢琴师
12: 楚门的世界
13: 三傻大闹宝莱坞
14: 机器人总动员
15: 放牛班的春天
16: 星际穿越
17: 大话西游之大圣娶亲
18: 熔炉
19: 疯狂动物城
20: 无间道
21: 龙猫
22: 教父
23: 当幸福来敲门
24: 怦然心动
25: 触不可及

到这里,是不是感觉很爽啊。 下面,我们做个更爽的,就是把这10页内容都搞下来。

直接上代码,在注释里详细说明:

import requests
from bs4 import BeautifulSoup

host = 'movie.douban.com' # 把这一块单拎出来,写起来更简便
j = 0
while j <= 9 : # 对整个代码块进行循环, 相当于从第一页到第十页全部爬一遍
    
    # 这里的url拆解分析,是重点!!! 如果url分析不出来,就没有后续的代码了
    # F12大法,打开network,看下面的url分析图。 在这个页面不要动,
    # 鼠标去点下一页,看看url有什么变化?
    # 有没有发现,第一页的start值是0, 第二页的start值是25, 第三页的start值是50...以此类推
    # 于是,就可以得到我们的动态url了! 如下:
    url = 'https://' + host +'/top250?start=' + str(j * 25)
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        # 'Accept-Encoding': 'gzip, deflate, br',
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive',
        'Cookie': 'douban-fav-remind=1; bid=QhopwFw0HcQ; __utmz=30149280.1586506561.6.5.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; _pk_ses.100001.4cf6=*; __utma=30149280.1613818664.1547469206.1586506561.1594137884.7; __utmb=30149280.0.10.1594137884; __utmc=30149280; __utma=223695111.510808800.1561795806.1561795806.1594137884.2; __utmb=223695111.0.10.1594137884; __utmc=223695111; __utmz=223695111.1594137884.2.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); ap_v=0,6.0; _pk_id.100001.4cf6=b46c129b3f0ba258.1561795806.2.1594137900.1561795859.',
        'Host': host,
        'Sec-Fetch-Mode': 'navigate',
        'Sec-Fetch-Site': 'none',
        'Sec-Fetch-User': '?1',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'
        }
    res = requests.get(url, headers=headers)
    html = res.text
    soup = BeautifulSoup(html, 'html.parser')
    # print(html)
    # print(soup)
    # 因为a标签里面有不止1个span,电影名字是在第一个span里,所以 我们要获取到第一个span。
    spans = soup.select('#content > div > div.article > ol > li > div > div.info > div.hd > a > span:nth-child(1)')
    # print(spans)
    
    # 再值得说的一点 就是这里i的值的变化了
    # 注意i 和j 的关系, 即每一页开头的电影名的序号 和页数的关系
    i = j*25 + 1 
    for span in spans:
        # print(span)
        print(str(i)+':',  span.text)
        i += 1

    # print(headers['Host'])
    # print(host)

    j += 1

url分析图:
在这里插入图片描述
好了,大致就是这样了。
这个代码还有地方可以改进,比如得到的结果写进Excel表格里。
大家可以自己试一下啊~~

猜你喜欢

转载自blog.csdn.net/tuzi007a/article/details/107195093