进入jupyter notebook
url链接:豆瓣TOP250
首先,在拿到一个网页后,要先了解该网页的结构,对这个网页进行分析。拿豆瓣top250来说,它的第一页的网址是:https://movie.douban.com/top250?start=0&filter=
第二页网址是:
https://movie.douban.com/top250?start=25&filter=
第三页网址为:
https://movie.douban.com/top250?start=50&filter=
……
网址中加粗的部分即为这几个网址不一样的地方,而且我们还能从中发现一个规律:加粗部分后一个为前一个加上25!
既然每一页的网址之间存在规律,那么我们可以将每一页的网址先拿到,将上面网址加粗部分替换为%s,后面的%page为网址中要替换的内容:
for page in range(0, 226, 25):
url = 'https://movie.douban.com/top250?start=%s&filter='%page
print (url)
ctrl+enter运行,结果如下:
我们再将鼠标放在豆瓣top250页面的任意位置,右击鼠标,选择检查:
然后点击network,按Ctrl+R刷新(也可以点击浏览器左上角的刷新),然后找到name下的第一个,单击,然后在该栏右侧找到headers,点击headers:
从里面可以看出,网页的请求方式为get,如果返回200即请求成功。
下面开始爬虫实战:
一、爬取网页
1. 请求源代码
#Win + R,输入cmd,回车,安装requests:
pip install requests
#headers的用法不会的可以百度
#爬取网页
#1.请求源代码
#安装requests
import requests
test_url = 'https://movie.douban.com/top250?start=0&filter='
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36'
}
#向服务器发出请求,返回200则为成功
response = requests.get(url = test_url,headers = headers).text
运行后会发现什么都没收到,这就是网页的反爬虫机制,如果我们要收到东西,那么就要对浏览器进行伪装:
二、筛选信息
from lxml import etree
import re, csv
#安装lxml: pip install lxml
#创建文件夹并打开
fp = open("./豆瓣top250.csv",'a', newline='',encoding='utf-8-sig')
writer = csv.writer(fp)
#写入内容
writer.writerow(('排名','名称','链接','星级','评分','评价人数'))
html_etree = etree.HTML(response)
#过滤
li = html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
#//*[@id="content"]/div/div[1]/ol/li的来源:将鼠标光标放到电影名称上右击,点击检查,然后在定位的地方右击鼠标,选择copy-->copy xpath,
#得到//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1],同样的方法放到第二个电影名称上复制其xpath
#得到//*[@id="content"]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a/span[1]
#可以看出两个xpth就li的部分不一样,如果我们复制第一个,它打印出来的就只有第一个电影,但我们要的是所有,所以复制到li
for item in li:
#排名,xpath后面的和上面的原理是一样的,下面也是,前面加了个.表示前面的是被省略了的,后面的text()表示我们要是的文本,[0]表示将字符串表示为数字
rank = item.xpath('./div/div[1]/em/text()')[0]
#print(rank)
name = item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]
dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
rating = re.findall('rating(.*?)-t',rating)[0]#(.*?)用来替换需要提取的地方
if len(rating) == 2:
star = int(rating)/10
else:
star = rating
rating_num = item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
content = item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
content = re.sub(r'\D',"",content)
print(rank, name, dy_url, rating, rating_num, content)
writer.writerow((rank, name, dy_url, rating, rating_num, content))
fp.close()
运行结果:
代码汇总:
import requests, re, csv
from lxml import etree
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36'
}
#创建文件夹并打开
fp = open("./豆瓣top250.csv",'a', newline='',encoding='utf-8-sig')
writer = csv.writer(fp)
#写入内容
writer.writerow(('排名','名称','链接','星级','评分','评价人数'))
for page in range(0,226,25):
url = 'https://movie.douban.com/top250?start=%s&filter='%page
print (url)
#向服务器发出请求,返回200则为成功
response = requests.get(url = url,headers = headers).text
html_etree = etree.HTML(response)
#过滤
li = html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
#//*[@id="content"]/div/div[1]/ol/li的来源:将鼠标光标放到电影名称上右击,点击检查,然后在定位的地方右击鼠标,选择copy-->copy xpath,
#得到//*[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1],同样的方法放到第二个电影名称上复制其xpath
#得到//*[@id="content"]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a/span[1]
#可以看出两个xpth就li的部分不一样,如果我们复制第一个,它打印出来的就只有第一个电影,但我们要的是所有,所以复制到li
for item in li:
#排名,xpath后面的和上面的原理是一样的,下面也是,前面加了个.表示前面的是被省略了的,后面的text()表示我们要是的文本,[0]表示将字符串表示为数字
rank = item.xpath('./div/div[1]/em/text()')[0]
#print(rank)
name = item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]
dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
rating = re.findall('rating(.*?)-t',rating)[0]#(.*?)用来替换需要提取的地方
if len(rating) == 2:
star = int(rating)/10
else:
star = rating
rating_num = item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
content = item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
content = re.sub(r'\D',"",content)
print(rank, name, dy_url, rating, rating_num, content)
writer.writerow((rank, name, dy_url, rating, rating_num, content))
fp.close()
运行结果如下: