目录
一、完整代码
成功运行的代码(暂未加入爬取完整250条的循环,待更新)供参考:
'''
step1 数据获取_requests
用开发者工具F12调出页面源代码,观察所需要的数据储存位置
如果储存在http页面中(服务器加载数据),可直接抓取
如果储存在其它地方,用抓包工具
发送请求,获得text版源码
用print检查无误后,将text版源码赋值存入a
step2 用re提取所需信息_re
写好正则obj = re.compile('正则规则',re.S)
赋值result = obj.finditer('a')
用for in 循环抓取匹配正则的信息
用print检查无误后,将抓取字段赋值存入dic
step3 将数据写入csv
'''
# step1 数据获取
import requests
url = 'https://movie.douban.com/top250'
headers = {'User-Agent': '马赛克我的信息'}
resp = requests.get(url,headers=headers)
content = resp.text # 先用print(resp.text)看是否出数据,然后再赋值
a=content.replace('\n',' ') # 去掉换行符 否则后面非常麻烦
resp.close() # 关掉response,防止被豆瓣封IP
# step2 解析数据
import re
import csv
obj = re.compile(r'<li>.*?<span class="title">(?P<电影名>.*?)</span>.*?<p class="">'
r'.*?<br>(?P<年份>.*?) .*?property="v:average">'
r'(?P<评分>.*?)</span>')
result = obj.finditer(a)
f = open('data.csv',mode='w',encoding='utf-8-sig') # 中文需要设置成utf-8格式
csvwriter = csv.writer(f)
for i in result: # 先用print(i.group('组名')看是否出数据,然后再赋值
# print(i.group('电影名').strip())
# print(i.group('年份').strip())
# print(i.group('评分').strip())
#.strip()是去掉空格
dic = i.groupdict()
dic['电影名'] = dic['电影名'].strip()
dic['年份'] = dic['年份'].strip()
csvwriter.writerow(dic.values())
f.close()
print('over')
二、问题总结
以下是我爬虫豆瓣时遇到的报错问题,给同样报错的各位做参考:
(一)因换行符导致正则匹配错误
我在正则匹配时,遇到换行必须用\n换行符才能抓取成功,导致过程非常麻烦,正则冗长:
obj = re.compile(r'<span class="title">(?P<电影名>.*?)</span>\n.*?\n.*?\n.*?\n\n\n.*?\n.*?\n.*?\n.*?\n.*?<br>\n'
r'(?P<年份>.*?) .*?\n.*?\n\n.*?\n.*?\n.*?\n.*?"v:average">'
r'(?P<评分>.*?)</span>')
这种死亡正则都被我写出来(并成功运行了)
解决:爬取步骤的时候就替换掉换行符,这样后面正则就不用管换行符了:
resp = requests.get(url,headers=headers)
content = resp.text
a=content.replace('\n',' ')
(二)编码有问题导致无法打印
print时候报错:UnicodeEncodeError: 'gbk' codec can't encode character '\xee' in position 21930: illegal multibyte
解决:修改编码,代码如下
import requests
import re
import io
import sys
# 改变标准输出的默认编码
# utf-8中文乱码
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='gb18030')
(三)csv文件中文乱码
解决:设置中文格式
在这一步加上encoding='utf-8-sig' :
f = open('data.csv',mode='w',encoding='utf-8-sig')