这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
Python urllib 库用于操作网页 URL,并对网页的内容进行抓取处理。
请求头
headers = {
'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
'Referer': 'https://*******'
}
请求头可以伪装成真机,假装自己在操作浏览,不容易被发现。 User-Agent,Referer, Cookie都可以在网页通过右击检查,在NetWork的请求里面去找到
是一个反爬方法,当然还可以收集一堆User-Agent的方式,或者是随机生成User-Agent 等,还可以在爬完几个页面之后睡一下,我一般就睡2秒的样子
爬取
路径我就不详细写出来啦,我们代入自己的就可以了,我现在需要爬取电影数据做简单分析,选了3个类别
DICT = {"喜剧": "https://s/1---喜剧--------.html",
"爱情": "https://s/1---爱情--------.html",
"动作": "https://s/1---动作--------.html"}
将爬取到的数据存到data.csv里面,有电影名、电影评分、电影类别、电影导演、地区、年份 6个字段
f = open("data.csv", "w", encoding='utf-8', newline='')
writer = csv.writer(f)
writer.writerow(['movie_title', 'movie_score', 'movie_type', 'movie_director', 'movie_region', 'movie_year'])
写完了再关上 f.close()
先贴上完整代码:
for kind in DICT:
url = DICT[kind]
url = quote(url, safe=string.printable)
request = Request(url, headers=headers)
res = urlopen(request)
with open("./tempFile/" + kind + ".html", 'wb') as f:
f.write(res.read())
with open("./tempFile/" + kind + ".html", 'r', encoding='utf-8') as f:
data = f.read()
soup = BeautifulSoup(data, "html.parser")
node_list = soup.find("ul", class_="myui-vodlist").findAll("li")
for li in node_list:
movie_detailUrl = "https://s/" + li.find("h4", class_="title").find("a")['href']
movie_title = li.find("h4", class_="title").find("a").get_text()
movie_score = li.find("span", class_="pic-tag").get_text()
movie_director, movie_region, movie_year = get_movieInfo(movie_detailUrl)
writer.writerow([movie_title, movie_score, kind, movie_director, movie_region, movie_year])
print(movie_title, movie_detailUrl, kind, movie_director, movie_region, movie_year)
# time.sleep(2)
f.close()
url = quote(url, safe=string.printable)这个的意思就是解决路径里面有中文的,会帮你转换;
"./tempFile/" + kind + ".html" 存到这个路径里面再去读会比较安全一点,当然也可以不用;
soup = BeautifulSoup(data, "html.parser") 使用BeautifulSoup会比较方便简单易懂,像scrapy的路径查找方法我就有点晕了。
soup.find("ul", class_="myui-vodlist").findAll("li") 像这个就是查找class为myui-vodlist的ul里面所有的li元素
find("a").get_text() 这个就是把a里面的文字取出来
解压缩读取
在get_movieInfo函数里面去获取另一个页面我们需要的内容,在这个页面也是一样的获取方法,不过我这个页面它需要解压缩才能读取,初学,也是第一次遇到😥 所以我们现在多了一步,在获取请求后,使用io流读取,然后解压缩
res = urlopen(request)
htmls = res.read()
buff = BytesIO(htmls)
ff = gzip.GzipFile(fileobj=buff)
htmls = ff.read()
敲重点了! 我们一点要在请求头里面加上这个 "Accept-Encoding": "gzip" ,灰常重要,重要到什么地步呢,就是不写会报错😯
这次取数据停让我头疼的
我本来是取最后两个a.get_text(), 但是它年份要是未知,最后一个a可能就是地区了
解决方法就是取出里面所有的字(没有元素的内容)进行分割,是我太傻了😖
aaa = soup.find("p", class_="data").text
list = str(aaa).replace('\xa0', ' ').split(" ")
index = -1
li = []
for i in list:
if i != '':
li.append(i)
movie_year = li[index].split(':')[1]
把取到的数据存到csv里面 就可以了😄
writer.writerow([movie_title, movie_score, kind, movie_director, movie_region, movie_year])