当前位置:   article > 正文

基于scrapy的分布式爬虫抓取新浪微博个人信息和微博内容存入MySQL

新浪爬虫可视化

为了学习机器学习深度学习和文本挖掘方面的知识,需要获取一定的数据,新浪微博的大量数据可以作为此次研究历程的对象

一、环境准备

 
python 2.7 
scrapy框架的部署(可以查看上一篇博客的简要操作,传送门: 点击打开链接
mysql的部署(需要的资源百度网盘链接: 点击打开链接
heidiSQL数据库可视化
 
本人的系统环境是 win 64位的 所以以上环境都是需要兼容64位的
 
 

二、scrapy组件和数据流介绍

\

1、Scrapy architecture


组件Scrapy Engine

引擎负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。

调度器(Scheduler)

调度器从引擎接受request并将他们入队,以便之后引擎请求他们时提供给引擎。

下载器(Downloader)

下载器负责获取页面数据并提供给引擎,而后提供给spider。

Spiders

Spider是Scrapy用户编写用于分析response并提取item(即获取到的item)或额外跟进的URL的类。 每个spider负责处理一个特定(或一些)网站。Item PipelineItem Pipeline负责处理被spider提取出来的item。典型的处理有清理、 验证及持久化(例如存取到数据库中)。

下载器中间件(Downloader middlewares)

下载器中间件是在引擎及下载器之间的特定钩子(specific hook),处理Downloader传递给引擎的response。 其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。更多内容请看 下载器中间件(Downloader Middleware) 。

Spider中间件(Spider middlewares)

Spider中间件是在引擎及Spider之间的特定钩子(specific hook),处理spider的输入(response)和输出(items及requests)。 其提供了一个简便的机制,通过插入自定义代码来扩展Scrapy功能。更多内容请看 Spider中间件(Middleware) 。

 

 

2、数据流(Data flow)


Scrapy中的数据流由执行引擎控制,其过程如下:


1.引擎打开一个网站(open a domain),找到处理该网站的Spider并向该spider请求第一个要爬取的URL(s)。

2.引擎从Spider中获取到第一个要爬取的URL并在调度器(Scheduler)以Request调度。

3.引擎向调度器请求下一个要爬取的URL。

4.调度器返回下一个要爬取的URL给引擎,引擎将URL通过下载中间件(请求(request)方向)转发给下载器(Downloader)。

5.一旦页面下载完毕,下载器生成一个该页面的Response,并将其通过下载中间件(返回(response)方向)发送给引擎。

6.引擎从下载器中接收到Response并通过Spider中间件(输入方向)发送给Spider处理。

7.Spider处理Response并返回爬取到的Item及(跟进的)新的Request给引擎。

8.引擎将(Spider返回的)爬取到的Item给Item Pipeline,将(Spider返回的)Request给调度器。

9.(从第二步)重复直到调度器中没有更多地request,引擎关闭该网站。

以上组件和数据流的部分是参考别的的介绍,觉得描述的挺好,比较容易理解整个框架的结构。下面是干货:

三、scrapy工程对象

在你需要创建工程的目录底下启动cmd命令(按住shift键右键选择在此处打开命令窗口) 执行:scrapy startproject weibo
会在当前目录下生成scrapy框架的目录结构:
本人用的IDE是pycharm ,用IDE打开工程,工程最终的目录结构如图所示:


 
 

1、item.py的内容:

[python]  view plain  copy
 
  1. # encoding=utf-8  
  2.   
  3. from scrapy.item import Item, Field  
  4.   
  5.   
  6. class InformationItem(Item):  
  7.     #关注对象的相关个人信息  
  8.     _id = Field()  # 用户ID  
  9.     Info = Field() # 用户基本信息  
  10.     Num_Tweets = Field()  # 微博数  
  11.     Num_Follows = Field()  # 关注数  
  12.     Num_Fans = Field()  # 粉丝数  
  13.     HomePage = Field() #关注者的主页  
  14.   
  15.   
  16. class TweetsItem(Item):  
  17.     #微博内容的相关信息  
  18.     _id = Field()  # 用户ID  
  19.     Content = Field()  # 微博内容  
  20.     Time_Location = Field()  # 时间地点  
  21.     Pic_Url = Field()  # 原图链接  
  22.     Like = Field()  # 点赞数  
  23.     Transfer = Field()  # 转载数  
  24.     Comment = Field()  # 评论数  

定义了两个类,InformationItem获取关注列表用户的个人信息,TweetsItem获取微博内容

2、weibo_spider.py的内容:

[python]  view plain  copy
 
  1. # coding=utf-8  
  2. from scrapy.spider import Spider  
  3. from scrapy.http import Request  
  4. from scrapy.selector import Selector  
  5. from weibo.items import InformationItem,TweetsItem  
  6. import re  
  7. import requests  
  8. from bs4 import BeautifulSoup  
  9.   
  10.   
  11.   
  12. class Weibo(Spider):  
  13.     name = "weibospider"  
  14.     redis_key = 'weibospider:start_urls'  
  15.     #可以从多个用户的关注列表中获取这些用户的关注对象信息和关注对象的微博信息  
  16.     start_urls = ['http://weibo.cn/0123456789/follow','http://weibo.cn/0123456789/follow']  
  17.     #如果通过用户的分组获取关注列表进行抓取数据,需要调整parse中如id和nextlink的多个参数  
  18.     #strat_urls = ['http://weibo.cn/attgroup/show?cat=user¤tPage=2&rl=3&next_cursor=20&previous_cursor=10&type=opening&uid=1771329897&gid=201104290187632788&page=1']  
  19.     url = 'http://weibo.cn'  
  20.     #group_url = 'http://weibo.cn/attgroup/show'  
  21.     #把已经获取过的用户ID提前加入Follow_ID中避免重复抓取  
  22.     Follow_ID = ['0123456789']  
  23.     TweetsID = []  
  24.   
  25.     def parse(self,response):  
  26.         #用户关注者信息  
  27.         informationItems = InformationItem()  
  28.         selector = Selector(response)  
  29.   
  30.         print selector  
  31.         Followlist = selector.xpath('//tr/td[2]/a[2]/@href').extract()  
  32.         print "输出关注人ID信息"  
  33.         print len(Followlist)  
  34.   
  35.         for each in Followlist:  
  36.             #选取href字符串中的id信息  
  37.             followId = each[(each.index("uid")+4):(each.index("rl")-1)]  
  38.             print followId  
  39.             follow_url = "http://weibo.cn/%s" % followId  
  40.             #通过筛选条件获取需要的微博信息,此处为筛选原创带图的微博  
  41.             needed_url = "http://weibo.cn/%s/profile?hasori=1&haspic=1&endtime=20160822&advancedfilter=1&page=1" % followId  
  42.             print follow_url  
  43.             print needed_url  
  44.             #抓取过数据的用户不再抓取:  
  45.             while followId not in self.Follow_ID:  
  46.                 yield Request(url=follow_url, meta={"item": informationItems, "ID": followId, "URL": follow_url}, callback=self.parse1)  
  47.                 yield Request(url=needed_url, callback=self.parse2)  
  48.                 self.Follow_ID.append(followId)  
  49.   
  50.         nextLink = selector.xpath('//div[@class="pa"]/form/div/a/@href').extract()  
  51.         #查找下一页,有则循环  
  52.         if nextLink:  
  53.             nextLink = nextLink[0]  
  54.             print nextLink  
  55.             yield Request(self.url + nextLink, callback=self.parse)  
  56.         else:  
  57.             #没有下一页即获取完关注人列表之后输出列表的全部ID  
  58.             print self.Follow_ID  
  59.             #yield informationItems  
  60.   
  61.     def parse1(self, response):  
  62.         """ 通过ID访问关注者信息 """  
  63.         #通过meta把parse中的对象变量传递过来  
  64.         informationItems = response.meta["item"]  
  65.         informationItems['_id'] = response.meta["ID"]  
  66.         informationItems['HomePage'] = response.meta["URL"]  
  67.         selector = Selector(response)  
  68.         #info = ";".join(selector.xpath('//div[@class="ut"]/text()').extract())  # 获取标签里的所有text()  
  69.         info = selector.xpath('//div[@class="ut"]/span[@class="ctt"]/text()').extract()  
  70.         #用/分开把列表中的各个元素便于区别不同的信息  
  71.         allinfo = '  /  '.join(info)  
  72.         try:  
  73.             #exceptions.TypeError: expected string or buffer  
  74.             informationItems['Info'] = allinfo  
  75.         except:  
  76.             pass  
  77.         #text2 = selector.xpath('body/div[@class="u"]/div[@class="tip2"]').extract()  
  78.         num_tweets = selector.xpath('body/div[@class="u"]/div[@class="tip2"]/span/text()').extract()  # 微博数  
  79.         num_follows = selector.xpath('body/div[@class="u"]/div[@class="tip2"]/a[1]/text()').extract()  # 关注数  
  80.         num_fans = selector.xpath('body/div[@class="u"]/div[@class="tip2"]/a[2]/text()').extract()  # 粉丝数  
  81.         #选取'[' ']'之间的内容  
  82.         if num_tweets:  
  83.             informationItems["Num_Tweets"] = (num_tweets[0])[((num_tweets[0]).index("[")+1):((num_tweets[0]).index("]"))]  
  84.         if num_follows:  
  85.             informationItems["Num_Follows"] = (num_follows[0])[((num_follows[0]).index("[")+1):((num_follows[0]).index("]"))]  
  86.         if num_fans:  
  87.             informationItems["Num_Fans"] = (num_fans[0])[((num_fans[0]).index("[")+1):((num_fans[0]).index("]"))]  
  88.   
  89.         yield informationItems  
  90.   
  91.     #获取关注人的微博内容相关信息  
  92.     def parse2(self, response):  
  93.   
  94.         selector = Selector(response)  
  95.         tweetitems = TweetsItem()  
  96.         #可以直接用request的meta传递ID过来更方便  
  97.         IDhref = selector.xpath('//div[@class="u"]/div[@class="tip2"]/a[1]/@href').extract()  
  98.         ID = (IDhref[0])[1:11]  
  99.         Tweets = selector.xpath('//div[@class="c"]')  
  100.   
  101.   
  102.         # 跟parse1稍有不同,通过for循环寻找需要的对象  
  103.         for eachtweet in Tweets:  
  104.             #获取每条微博唯一id标识  
  105.             mark_id = eachtweet.xpath('@id').extract()  
  106.             print mark_id  
  107.             #当id不为空的时候加入到微博获取列表  
  108.             if mark_id:  
  109.                 #去重操作,对于已经获取过的微博不再获取  
  110.                 while mark_id not in self.TweetsID:  
  111.                     content = eachtweet.xpath('div/span[@class="ctt"]/text()').extract()  
  112.                     timelocation = eachtweet.xpath('div[2]/span[@class="ct"]/text()').extract()  
  113.                     pic_url = eachtweet.xpath('div[2]/a[2]/@href').extract()  
  114.                     like = eachtweet.xpath('div[2]/a[3]/text()').extract()  
  115.                     transfer = eachtweet.xpath('div[2]/a[4]/text()').extract()  
  116.                     comment = eachtweet.xpath('div[2]/a[5]/text()').extract()  
  117.   
  118.                     tweetitems['_id'] = ID  
  119.                     #把列表元素连接且转存成字符串  
  120.                     allcontents = ''.join(content)  
  121.                     #内容可能为空 需要先判定  
  122.                     if allcontents:  
  123.                         tweetitems['Content'] = allcontents  
  124.                     else:  
  125.                         pass  
  126.                     if timelocation:  
  127.                         tweetitems['Time_Location'] = timelocation[0]  
  128.                     if pic_url:  
  129.                         tweetitems['Pic_Url'] = pic_url[0]  
  130.                     # 返回字符串中'[' ']'里的内容  
  131.                     if like:  
  132.                         tweetitems['Like'] = (like[0])[((like[0]).index("[")+1):((like[0]).index("]"))]  
  133.                     if transfer:  
  134.                         tweetitems['Transfer'] = (transfer[0])[((transfer[0]).index("[")+1):((transfer[0]).index("]"))]  
  135.                     if comment:  
  136.                         tweetitems['Comment'] = (comment[0])[((comment[0]).index("[")+1):((comment[0]).index("]"))]  
  137.                     #把已经抓取过的微博id存入列表  
  138.                     self.TweetsID.append(mark_id)  
  139.                     yield tweetitems  
  140.             else:  
  141.                 #如果selector语句找不到id 查看当前查询语句的状态  
  142.                 print eachtweet  
  143.   
  144.         tweet_nextLink = selector.xpath('//div[@class="pa"]/form/div/a/@href').extract()  
  145.         if tweet_nextLink:  
  146.             tweet_nextLink = tweet_nextLink[0]  
  147.             print tweet_nextLink  
  148.             yield Request(self.url + tweet_nextLink, callback=self.parse2)  

每个微博用户都有唯一的标识uid,此uid是获取需要对象的关键。修改start_url里面的ID(0123456789),比如换成留几手的ID(1761179351),即把地址换成你想获取的用户的关注人列表的信息,可以对多个用户的关注列表用redis_keyf方式进行分布式操作。内容比较多就不一一介绍,代码不理解的可以留言探讨,本人也是模仿着别人的框架写出来的代码,不是科班出身,代码写的比较渣渣,大神可以帮忙指点一二。
 

3、获取cookies模拟登陆微博:

[python]  view plain  copy
 
  1. # encoding=utf-8  
  2.   
  3. import requests  
  4. from selenium import webdriver  
  5. import time  
  6. from PIL import Image  
  7. import urllib2  
  8. from bs4 import BeautifulSoup  
  9. import re  
  10. import urllib  
  11.   
  12.   
  13. #多点账号防止被和谐  
  14.   
  15. myAccount = [  
  16.     {'no': 'XXXXXXXXXX', 'psw': 'XXXXXXXXX'},  
  17.     {'no': 'XXXXXXXX', 'psw': 'XXXXXXX'},  
  18.     {'no': 'XXXXXX', 'psw': 'XXXXXXX'}  
  19. ]  
  20.   
  21. headers={  
  22.     "Host":"login.weibo.cn",  
  23.     "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",  
  24.     "Accept":'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',  
  25.     "Accept-Language":"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",  
  26.     "Accept-Encoding":"gzip, deflate",  
  27.     "Connection":"keep-alive"  
  28. }  
  29.   
  30. # 获取验证码等相关登录信息  
  31. def get_captchainfo(loginURL):  
  32.     html = requests.get(loginURL).content  
  33.     bs = BeautifulSoup(html)  
  34.     #print bs  
  35.     #注意通过bs.select元素寻找对象,返回的是列表对象  
  36.     password_name = (bs.select('input[type="password"]'))[0].get('name')  
  37.     vk = (bs.select('input[name="vk"]'))[0].get('value')  
  38.     capId = (bs.select('input[name="capId"]'))[0].get('value')  
  39.     print password_name,vk,capId  
  40.     try:  
  41.         captcha_img = bs.find("img", src=re.compile('http://weibo.cn/interface/f/ttt/captcha/')).get('src')  
  42.         print captcha_img  
  43.         #captchaid可以从验证码图片地址中直接截取获得  
  44.         urllib.urlretrieve(captcha_img, 'captcha.jpg')  
  45.         print "captcha download success!"  
  46.         captcha_input = input("please input the captcha\n>")  
  47.     except:  
  48.         return None  
  49.   
  50.     return (captcha_input,password_name,vk,capId)  
  51.   
  52.   
  53.   
  54. def getCookies(weibo):  
  55.     """ 获取Cookies """  
  56.     cookies = []  
  57.     loginURL = 'http://login.weibo.cn/login/'  
  58.     for elem in weibo:  
  59.         account = elem['no']  
  60.         password = elem['psw']  
  61.         captcha = get_captchainfo(loginURL)  
  62.         if captcha[0] is None:  
  63.             #不需要验证码时的表单,微博移动网页版都要验证码,此处可以忽略  
  64.             postData = {  
  65.                     "source": "None",  
  66.                     "redir": "http://weibo.cn/",  
  67.                     "mobile": account,  
  68.                     "password": password,  
  69.                     "login": "登录",  
  70.             }  
  71.         else:  
  72.             #需要验证码时的表单  
  73.             print "提交表单数据"  
  74.             postData = {  
  75.                     "mobile": account,  
  76.                     captcha[1]: password,  
  77.                     "code": captcha[0],  
  78.                     "remember":"on",  
  79.                     "backurl": "http://weibo.cn/",  
  80.                     "backtitle":u'微博',  
  81.                     "tryCount":"",  
  82.                     "vk": captcha[2],  
  83.                     "capId": captcha[3],  
  84.                     "submit": u'登录',  
  85.             }  
  86.         print postData  
  87.         session = requests.Session()  
  88.         r = session.post(loginURL, data=postData, headers=headers)  
  89.         #判断post过后是否跳转页面  
  90.         #time.sleep(2)  
  91.         print r.url  
  92.         if r.url == 'http://weibo.cn/?PHPSESSID=&vt=1'or 'http://weibo.cn/?PHPSESSID=&vt=4':  
  93.             ceshihtml = requests.get(r.url).content  
  94.             print ceshihtml  
  95.             print 'Login successfully!!!'  
  96.             cookie = session.cookies.get_dict()  
  97.             cookies.append(cookie)  
  98.         else:  
  99.             print "login failed!"  
  100.   
  101.     return cookies  
  102.   
  103. ''''' 
  104. #通过selenium driver方式获取cookie 
  105. def getcookieByDriver(weibo): 
  106.     driver = webdriver.Firefox() 
  107.     driver.maximize_window() 
  108.     cookies = [] 
  109.     for elem in weibo: 
  110.         account = elem['no'] 
  111.         password = elem['psw'] 
  112.         driver.get("http://login.weibo.cn/login/") 
  113.         elem_user = driver.find_element_by_name("mobile") 
  114.         elem_user.send_keys(account)  # 用户名 
  115.         #微博的password有加后缀, 
  116.         elem_pwd = driver.find_element_by_name("password_XXXX") 
  117.         elem_pwd.send_keys(password)  # 密码 
  118.         time.sleep(10) 
  119.         #手动输验证码时间 
  120.         elem_sub = driver.find_element_by_name("submit") 
  121.         elem_sub.click()  # 点击登陆 
  122.         time.sleep(2) 
  123.         weibo_cookies = driver.get_cookies() 
  124.         #cookie = [item["name"] + "=" + item["value"] for item in douban_cookies] 
  125.         #cookiestr = '; '.join(item for item in cookie) 
  126.         cookies.append(weibo_cookies) 
  127.     return cookies 
  128. '''  
  129.   
  130. cookies = getCookies(myAccount)  
  131. #cookies = getcookieByDriver(myAccount)  
  132. print "Get Cookies Finish!( Num:%d)" % len(cookies)  

在myAcount中输入你自己拥有的微博账号密码,就可以模拟登陆微博啦:
这里有两种方式:
【1】模拟浏览器提交表单登陆(推荐)
【2】通过selenium WebDriver 方式登陆
验证码暂时还是先手动输一下吧,还没有找到快速有效的方式破解。
反正只要拿到cookie保存下来就可以进行抓取操作啦。
 

4、数据管道pipeline存入MySQL数据库:

[python]  view plain  copy
 
  1. # -*- coding: utf-8 -*-  
  2. import MySQLdb  
  3. from items import InformationItem,TweetsItem  
  4.   
  5. DEBUG = True  
  6.   
  7. if DEBUG:  
  8.     dbuser = 'root'  
  9.     dbpass = '123456'  
  10.     dbname = 'tweetinfo'  
  11.     dbhost = '127.0.0.1'  
  12.     dbport = '3306'  
  13. else:  
  14.     dbuser = 'XXXXXXXX'  
  15.     dbpass = 'XXXXXXX'  
  16.     dbname = 'tweetinfo'  
  17.     dbhost = '127.0.0.1'  
  18.     dbport = '3306'  
  19.   
  20.   
  21. class MySQLStorePipeline(object):  
  22.     def __init__(self):  
  23.         self.conn = MySQLdb.connect(user=dbuser, passwd=dbpass, db=dbname, host=dbhost, charset="utf8",  
  24.                                     use_unicode=True)  
  25.         self.cursor = self.conn.cursor()  
  26.         #建立需要存储数据的表  
  27.   
  28.         # 清空表(测试阶段):  
  29.         self.cursor.execute("truncate table followinfo;")  
  30.         self.conn.commit()  
  31.         self.cursor.execute("truncate table tweets;")  
  32.         self.conn.commit()  
  33.   
  34.     def process_item(self, item, spider):  
  35.         #curTime = datetime.datetime.now()  
  36.         if isinstance(item, InformationItem):  
  37.             print "开始写入关注者信息"  
  38.             try:  
  39.                 self.cursor.execute("""INSERT INTO followinfo (id, Info, Num_Tweets, Num_Follows, Num_Fans, HomePage) 
  40.                                 VALUES (%s, %s, %s, %s, %s, %s)""",  
  41.                                     (  
  42.                                         item['_id'].encode('utf-8'),  
  43.                                         item['Info'].encode('utf-8'),  
  44.                                         item['Num_Tweets'].encode('utf-8'),  
  45.                                         item['Num_Follows'].encode('utf-8'),  
  46.                                         item['Num_Fans'].encode('utf-8'),  
  47.                                         item['HomePage'].encode('utf-8'),  
  48.                                     )  
  49.                                     )  
  50.   
  51.                 self.conn.commit()  
  52.             except MySQLdb.Error, e:  
  53.                 print "Error %d: %s" % (e.args[0], e.args[1])  
  54.   
  55.         elif isinstance(item, TweetsItem):  
  56.             print "开始写入微博信息"  
  57.             try:  
  58.                 self.cursor.execute("""INSERT INTO tweets (id, Contents, Time_Location, Pic_Url, Zan, Transfer, Comment) 
  59.                                 VALUES (%s, %s, %s, %s, %s, %s, %s)""",  
  60.                                     (  
  61.                                         item['_id'].encode('utf-8'),  
  62.                                         item['Content'].encode('utf-8'),  
  63.                                         item['Time_Location'].encode('utf-8'),  
  64.                                         item['Pic_Url'].encode('utf-8'),  
  65.                                         item['Like'].encode('utf-8'),  
  66.                                         item['Transfer'].encode('utf-8'),  
  67.                                         item['Comment'].encode('utf-8')  
  68.                                     )  
  69.                                     )  
  70.                 self.conn.commit()  
  71.   
  72.             except MySQLdb.Error, e:  
  73.                 print "出现错误"  
  74.                 print "Error %d: %s" % (e.args[0], e.args[1])  
  75.   
  76.         return item  

MySQL部署好之后只要输入自己的用户名密码就可以存到数据库当中去
因为我的创建表格没有写到pipeline中,就先自己建好数据库和表格好了:
需要注意的是:为了让mysql正常显示中文,在建立数据库的时候使用如下语句:
[sql]  view plain  copy
 
  1. CREATE DATABASE tweetinfo DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;  
数据库目录结构:
 
 
创建 表格followinfo
[sql]  view plain  copy
 
  1. CREATE TABLE `followinfo` (  
  2.     `No` INT(11) NOT NULL AUTO_INCREMENT,  
  3.     `id` VARCHAR(50) NULL DEFAULT NULL,  
  4.     `Info` VARCHAR(100) NOT NULL,  
  5.     `Num_Tweets` INT(10) NOT NULL,  
  6.     `Num_Follows` INT(10) NOT NULL,  
  7.     `Num_Fans` INT(10) NOT NULL,  
  8.     `HomePage` VARCHAR(50) NOT NULL,  
  9.     PRIMARY KEY (`No`)  
  10. )  
  11. COLLATE='utf8_general_ci'  
  12. ENGINE=MyISAM  
  13. AUTO_INCREMENT=5  
  14. ;  


创建表格tweets
[sql]  view plain  copy
 
  1. CREATE TABLE `tweets` (  
  2.     `No` INT(11) NOT NULL AUTO_INCREMENT,  
  3.     `id` VARCHAR(20) NOT NULL,  
  4.     `Contents` VARCHAR(300) NULL DEFAULT NULL,  
  5.     `Time_Location` VARCHAR(50) NOT NULL,  
  6.     `Pic_Url` VARCHAR(100) NULL DEFAULT NULL,  
  7.     `Zan` INT(10) NOT NULL,  
  8.     `Transfer` INT(10) NOT NULL,  
  9.     `Comment` INT(10) NOT NULL,  
  10.     PRIMARY KEY (`No`)  
  11. )  
  12. COLLATE='utf8_general_ci'  
  13. ENGINE=MyISAM  
  14. AUTO_INCREMENT=944  
  15. ;  

5、中间组建middleware:

[python]  view plain  copy
 
  1. # encoding=utf-8  
  2. import random  
  3. from cookies import cookies  
  4. from user_agents import agents  
  5.   
  6.   
  7. class UserAgentMiddleware(object):  
  8.     """ 换User-Agent """  
  9.   
  10.     def process_request(self, request, spider):  
  11.         agent = random.choice(agents)  
  12.         request.headers["User-Agent"] = agent  
  13.   
  14.   
  15. class CookiesMiddleware(object):  
  16.     """ 换Cookie """  
  17.   
  18.     def process_request(self, request, spider):  
  19.         cookie = random.choice(cookies)  
  20.         request.cookies = cookie  



 
   
 

6、设置相关settings:

[python]  view plain  copy
 
  1. # coding=utf-8  
  2.   
  3. BOT_NAME = 'weibo'  
  4.   
  5. SPIDER_MODULES = ['weibo.spiders']  
  6. NEWSPIDER_MODULE = 'weibo.spiders'  
  7.   
  8. USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'  
  9.   
  10. ''''' 
  11. #把数据存到路径中的CSV文件中去 
  12. FEED_URI = u'file:///G:/MovieData/followinfo.csv' 
  13. FEED_FORMAT = 'CSV' 
  14. '''  
  15.   
  16. DOWNLOADER_MIDDLEWARES = {  
  17.     "weibo.middleware.UserAgentMiddleware": 401,  
  18.     "weibo.middleware.CookiesMiddleware": 402,  
  19. }  
  20.   
  21.   
  22. ITEM_PIPELINES = {  
  23.     #'weather2.pipelines.Weather2Pipeline': 300,  
  24.     'weibo.pipelines.MySQLStorePipeline': 300,  
  25. }  
  26.   
  27.   
  28. DOWNLOAD_DELAY = 2  # 下载器间隔时间  
  29.   
  30. # Crawl responsibly by identifying yourself (and your website) on the user-agent  
  31. #USER_AGENT = 'doubanmovie (+http://www.yourdomain.com)'  
 
数据爬取效果展示:

四、总结:

1、学习了解scrapy框架写代码熟悉数据流的流程收获还是很多的。
2、感觉不是太复杂的网站应该都是可以抓的。形成了自己的一套系统知识体系,具体情况具体分析吧。
3、验证码这块简单的还能识别,复杂的可能得稍微用点深度学习了,识别率很一般,暂时还是人工输入吧。
4、爬虫只是很入门的技术,后续需要学的东西还好多。
额,看到这里也是不容易,说了这么多,关键还是直接打包工程源码: 点击打开链接
 
 
转载:http://blog.csdn.net/zengsl233/article/details/52294760

转载于:https://www.cnblogs.com/c-x-a/p/8243354.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/208151?site
推荐阅读
相关标签
  

闽ICP备14008679号