上周四去公司,师哥让我把写的爬虫程序给大家讲了一下,然后点评了之后给可建议,让我根据建议修改那个程序。
需要修改的地方是以下几点
1. 使用requests 代维 urlib2
2. 使用CVS导出
3. 使用with
4. 请求方法和解析方法分开
5. 命名问题
在听了师哥指导之后,我开始进行改进。
昨天下午之前,修改后的程序已经执行成功。回首上面这几点,第二点是我花费了极大一部分时间。为什么呢?
先看下面这两电影的信息
千与千寻是250部电影里面大部分正常的电影信息,加标题的话,属性一共是11个
然而泰坦尼克号,看见没有?杀出个“官方网站”。但是有这个属性的比较少,后来在转csv时发现还不对,就继续看电影信息,结果有的还包括属性“官方小站”
就上面这两个属性是少数电影信息里面的包括的,所以要想办法,到这些电影的这两个属性的时候,跳过去!
结果以为万事大吉的时候,发现从txt导入csv还是不对!结果我就继续找问题,最后,说出来你可能不信,全部250部电影里面,居然有一部还是两部电影信息里面没有“编剧”,或者是“又名”。
当时我就蒙蔽了但是也清楚了,如果上面“官方网站”和“官方小站”是特别物种,那么这个“编剧”和”又名“其实就是异种啊!参杂在几乎所有电影信息里面的变了身的异种!必须除去!
所以最后,一切安静下来了。
# -*- coding: utf-8 -*-
import requests
import re
from bs4 import BeautifulSoup
import sys
import csv
reload(sys)
sys.setdefaultencoding("utf-8")
def get_subject(baseUrl):
try:
allText=''
for i in range(0,250,25):
res=requests.get(baseUrl+str(i)+'&fileter=')
allText=allText+res.text
except requests.HTTPError,e:
if hasattr(e, "reason"):
print u"链接失败,错误原因", e.reason
soup=BeautifulSoup(allText,'html.parser',from_encoding='UTF-8')
link_temp=soup.find_all('a',href=re.compile(r'subject'))
each_movie=[]
for i in range(0,500,2):
each_movie.append(link_temp[i])
return each_movie
def get_info(link):
movies=link
allInfomatio=[]
length=0
count = 0
try:
with open('250movies.txt', 'w') as file:
for enter in movies:
try:
res = requests.get(enter['href'])
print res.status_code
if res.status_code==200:
length += 1
print "获取电影数", length
infomation = res.text
soup1 = BeautifulSoup(infomation, 'html.parser', from_encoding='UTF-8')
info = soup1.find_all('div', id=re.compile(r'info'))
title = soup1.find_all('span',property=re.compile(r'v:itemreviewed'))
each_info = info
each_title = title
for link_t in each_title:
file.write(link_t.get_text())
file.seek(0,2)
for link_i in each_info:
file.write(link_i.get_text())
file.seek(0,2)
except requests.HTTPError, e:
print '找不到网页'
except IOError as e:
print "文件错误" + str(e)
try:
with open('250movies.txt','r') as rf:
while True:
line = rf.readline()
if line == '':
break
if line.split(':')[0] == '官方网站':
continue
if line.split(':')[0] == '又名':
continue
if line.split(':')[0] == "编剧":
continue
if line.split(':')[0] == "官方小站":
line = rf.readline()
continue
print line.split('\r')[0]
allInfomatio.append(line.split('\r')[0])
data=[("电影名","导演","主演","类型","制片国家","语言","上映日期","片长","IMDb链接")]
for i in range(0,count*9,9):
str = (allInfomatio[i], allInfomatio[i + 1].split(':')[1], allInfomatio[i + 2].split(':')[1],
allInfomatio[i + 3].split(':')[1], allInfomatio[i + 4].split(':')[1]
+ allInfomatio[i + 5].split(':')[1] + allInfomatio[i + 6].split(':')[1] + allInfomatio[i + 7].split(':')[
1] + allInfomatio[i + 8].split(':')[1] )
data.append(str)
except IOError, e:
print "文件错误" + str(e)
#现在data里面有的应该是关于所有信息的类似二维数组的样子,这次再写入csv文件
try:
with open('finalMovies.csv','w') as cwf:
spamwriter=csv.write(cwf,delimiter=' ')
for i in range(count):<span style="white-space:pre"> </span>//这里
spamwriter.writerow(data[i])
except IOError,e:
print "文件错误"+str(e)
def main():
list=get_subject('https://movie.douban.com/top250?start=')
get_info(list)
main()
今天看的时候发现csv里面少了最后一个电影信息,现在再看程序觉得是不是 “//这里”,应该是count+1吧,range里面是一个参数,意思是从0到count-1个数吧。
最后,我知道需要学习修改的地方还有很多,学习之路还在继续。 类似这个程序再修改可以把文件写入转换写在某一个函数里面