之前需要说的
- 关于爬虫
爬虫无处不在。搜索引擎是爬虫,抢票软件是爬虫,刷粉脚本是爬虫。可以说,按照一定的规则与网站进行交互的脚本或者程序都可以称作爬虫。爬虫可以是好的,Google的爬虫让你的个人网站可以被互联网中的任何一个人搜索到。爬虫也可以是坏的,各种技术黄牛和抢票软件让一般人无法通过正常渠道购票。
你遇到过坑人无比的验证码吗?你遇到过无穷无尽的右滑验证吗?这些只不过是爬虫与反爬虫战争中的冰山一角。
- robots协议
robots.txtrobots是网站跟爬虫间的协议,用简单直接的txt格式文本方式告诉对应的爬虫被允许的权限。如果在网站根目录下存在robots协议文件即robots.txt
,请务必据此编写爬虫。下面以淘宝为例说明。
打开淘宝根目录的协议文件,我们截取类似的两段文字https://www.taobao.com/robots.txt
User-agent: Baiduspider
Allow: /article
Allow: /oshtml
Allow: /ershou
Allow: /$
Disallow: /product/
Disallow: /
User-Agent: *
Disallow: /
我们注意到用户Baiduspider
(实际上就是百度搜索引擎爬虫)被拒绝爬取一些网址。而用户*
(代指出指定用户外其他一切用户)被拒绝爬取一切网址。也就是淘宝网不允许我们爬取淘宝的任何网页。
但实际上,robots协议并不能对爬虫的行为产生任何实质上的干涉。没有人能阻止你爬取淘宝的内容。(实际上许多比价网站正在这么做)
- Bangumi
一个非营利动画评分网站。服务器似乎在英国?或者是运用了针对ip的反爬虫手段?反正导致我用了比较特殊的办法(不断切换代理ip)才爬取成功。(说到底还是因为太菜了)http://bangumi.tv/
爬虫实现
先把代码放上来,有空慢慢写
(TO BE CONTINUED)
import requests,re,csv,pandas
from bs4 import BeautifulSoup
def get_html(url):
'''导入代理IP集'''
proxy_list=[]
with open('proxy.csv',encoding='utf_8') as csvfile:
r=csv.reader(csvfile)
for i in r:
proxy_list.append(i)
'''爬取html'''
#定义循环变量表示代理IP
i=0
while True:
#当需要的代理IP数超过实际数目时退出
if i>500:
print("wrong!")
quit()
#当此IP无法爬取时重启循环换下一个IP
try:
i+=1
#整理代理IP格式
proxy={'http':proxy_list[i][0]+':'+proxy_list[i][1]}
#模仿浏览器用户
kv={'user-agent':'Mozilla/5.0'}
#利用request爬取,利用BS整理
r=requests.get(url,headers=kv,proxies=proxy,timeout=30)
r.encoding=r.apparent_encoding
return BeautifulSoup(r.text,'html.parser')
except:
continue
def bangumi_spider():
namel=[]
scorel=[]
numberl=[]
#遍历1-209页
for i in range(1,210):
url='http://bangumi.tv/anime/browser?sort=rank&page='+str(i)
soup=get_html(url)
#爬取定位
try:
for tag in soup.find('ul',class_='browserFull').contents:
namel.append(tag.div.h3.a.text)
scorel.append(tag.find('small',class_='fade').text)
row_num=tag.find('span',class_='tip_j').text
fin_numl=re.findall('\d+',row_num)
numberl.append(fin_numl[0])
except:
print('Page',i,' error!')
continue
'''存储输出数据'''
fin_frame=pandas.DataFrame({'Anime Name':namel,'Bangumi Score':scorel,'Number of People':numberl})
print(fin_frame.head())
fin_frame.to_csv('Bangumi_Score_for_Anime.csv',index=0,encoding='utf_8_sig')
return
if __name__ == "__main__":
bangumi_spider()
One comment
这个名字很突出啊