澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站极客学院,爬到第10个信息以

2019-10-05 作者:www.8455.com   |   浏览(97)

微信是比较封闭的,微博的好友信息比较开放,都可以抓到;

Date:2016-12-6
By:Black Crow

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

selenium 爬取动态加载网站中途停止,爬到第10个信息以后不能再继续
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
import time

#coding=utf-8
**
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import time def login(user,pwd):
    driver.get(
")
    driver.maximize_window()
    time.sleep(2)
    driver.find_element_by_id('textfield').send_keys(user)
    time.sleep(2)
    driver.find_element_by_id('passwordfield').send_keys(pwd)
    time.sleep(2)
    driver.find_element_by_id('submitbutton').click()
    time.sleep(2)
    return driver
def logout():
    driver.find_element_by_id('logout').click()
    time.sleep(2)
    driver.quit()

1)找人,通过关注列表;
2)提取出微博的数据,放到数据库;

前言:

本次作业为课程第五部分的作业,模拟登陆豆瓣。主要使用的是selenium的webdriver模拟登陆,使用lxml来抓XPATH定位。

一、环境准备

 

python 2.7 

scrapy框架的部署(可以查看上一篇博客的简要操作,传送门:点击打开链接)

mysql的部署(需要的资源百度网盘链接:点击打开链接)

heidiSQL数据库可视化

 

本人的系统环境是 win 64位的 所以以上环境都是需要兼容64位的

 

 

driver = webdriver.Chrome()
driver.maximize_window()

if __name__ == "__main__":
    driver = webdriver.Chrome()
    driver = login('admin','abc123')
    t = driver.find_element_by_id('logout').text
    if t == u"登出":
        print ('登录成功')
    else:
        print ('登录失败')
    logout()

微博昵称,头像;
关注,粉丝及微博数量;
根据一些基本的原则来决定是否将该用户的微博入待爬的队列;

作业效果:

澳门新萄京官方网站 1

pic.png

二、scrapy组件和数据流介绍

澳门新萄京官方网站 2

def crawlHouseDetailForInvoke():
driver.find_element_by_class_name("collapsible-header").click()# price/tax history
time.sleep
table = driver.find_element_by_xpath('//div[@id = "wrapper"]/div/div/div/div/div[@id = "detail-container-column"]/div/div/main/div/div/div/div/div/section[3]/div/div/div/table')
print(table.text)

指标:关注人数;
粉丝人数;但是有可能会很多人,而且有很多僵尸粉;(不好:第一,低效;
第二,平台也不会让你无限制的往下翻页,肯定会有限制)
微博数,粉丝数的数量是个重要的参考点;

我的代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import lxml.html
def get_douban_info():
login_url ='https://accounts.douban.com/login'
driver = webdriver.Chrome()
driver.get(login_url)
account = driver.find_element_by_id('email')
account.clear()#清楚框框里的字,下同
account.send_keys('********')#真实账号被隐藏,请换成自己实际的账号
password =driver.find_element_by_id('password')
password.clear()
password.send_keys('***********')#真实密码被隐藏,请换成自己实际的密码
captcha = driver.find_element_by_id('captcha_image')
if captcha:#如果抓到验证码了,恭喜你,需要打码
captcha_field = driver.find_element_by_id('captcha_field')
captcha_field.clear()
captcha_field.send_keys(input('captcha is:'))#验证码手动挡
account.send_keys(Keys.RETURN)
else:#如果没有就直接回车吧
account.send_keys(Keys.RETURN)
html=driver.page_source#抓页面
selector= lxml.html.fromstring(html)#通过lxml来抓XPATH
content = selector.xpath('//div[@class="usr-pic"]/a/@href')
for url in content:
driver.get(url)
new_content =driver.page_source
selector1 =lxml.html.fromstring(new_content)
# print(new_content)
locations =selector1.xpath('//div[@class="user-info"]/a/text()')#抓的是list,下同
dates = selector1.xpath('//div[@class="pl"]/text()')
imgs = selector1.xpath('//div[@class="basic-info"]/img/@src')
intros = selector1.xpath('//span[@id="intro_display"]/text()')
new_intro =[]
for intro in intros:
intro=intro.strip().replace('n','').replace('xa0','')#去除换行等
new_intro.append(intro)
data = {
'url':url,
'location':locations[0],
'date':dates[1],
'img':imgs[0],
'intro':new_intro
}
print(data)
driver.close()#抓完关窗口
get_douban_info()

####总结:
>1. 手动打码好low逼,急需解决输入验证码的问题。

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) 。

 

 

def crawlRegion:
driver.get
div_parent = driver.find_element_by_id('list-results')
a_link = div_parent.find_elements_by_xpath('//div[@id = "search-results"]/ul/li/article/div/a')
print("information in this page:%d" % len
for i in range(len:
try:
print
print(a_link[i].get_attribute
a_link[i].click()
time.sleep
crawlHouseDetailForInvoke()
except Exception as e:
continue
finally:
driver.back()

怎么判断抓取的人不值得关注?可以先做一个定向的分析,分析你所抓的领域的人的微博大致情况;
    1)如果发布的微博数量特别少,可以认为是僵尸用户,不用爬;微博数小于某个下限;
    2)如果发布的微博数量特别多,比如每天发100多条,可能是小广告商或者机器人;
    3)对于转发的微博其实和僵尸的微博差不多,你可能爬了大量的微博发现都是重复的信息;

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,引擎关闭该网站。

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

if name == "__main__":

# 下面列出部分代码如下:

三、scrapy工程对象

在你需要创建工程的目录底下启动cmd命令(按住shift键右键选择在此处打开命令窗口) 执行:scrapy startproject weibo

会在当前目录下生成scrapy框架的目录结构:

本人用的IDE是pycharm ,用IDE打开工程,工程最终的目录结构如图所示:
澳门新萄京官方网站 3

 

 

regionUrl = "https://www.zillow.com/homes/recently_sold/Culver-City-CA/house,condo,apartment_duplex,townhouse_type/51617_rid/12m_days/globalrelevanceex_sort/34.05529,-118.33211,33.956531,-118.485919_rect/12_zm/"print("crawler is started...")crawlRegion(regionUrl)driver.close()driver.quit()

# -*- coding: utf-8 -*-
"""
Created on Sun Apr  1 10:18:42 2018

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获取微博内容

@author: Joe3223
"""
# -*- coding:utf-8 -*-
#!/usr/bin/env python3
import time
import os
import re
from bs4 import BeautifulSoup
from urllib.request import urlopen
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
#import pymongo
#from pymongo import MongoClient
import hashlib
from collections import deque
from lxml import etree
import threading

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 = [']  
  17.     #如果通过用户的分组获取关注列表进行抓取数据,需要调整parse中如id和nextlink的多个参数  
  18.     #strat_urls = [']  
  19.     url = ''  
  20.     #group_url = ''  
  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 = "" % followId  
  40.             #通过筛选条件获取需要的微博信息,此处为筛选原创带图的微博  
  41.             needed_url = "" % 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方式进行分布式操作。内容比较多就不一一介绍,代码不理解的可以留言探讨,本人也是模仿着别人的框架写出来的代码,不是科班出身,代码写的比较渣渣,大神可以帮忙指点一二。

 

# 数据库的准备,这里用的是mongodb;
#client = MongoClient('localhost',27017)
#db = client.test
#followers = db.followers

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('')  
  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 captchan>")  
  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 = ''  
  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": "",  
  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": "",  
  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 == ' '':  
  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("") 
  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保存下来就可以进行抓取操作啦。

 

# 注意:这里如果不设置user-agent,可能是无法跳转的
user_agent = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) "
    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36"
)
##dcap = dict(DesiredCapabilities.PHANTOMJS)
##dcap["phantomjs.page.settings.userAgent"] = user_agent
dcap = dict(DesiredCapabilities.FIREFOX)
dcap["firefox.page.settings.userAgent"] = user_agent

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;  

数据库目录结构:
澳门新萄京官方网站 4

 

 

创建 表格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. ;  

澳门新萄京官方网站 5

创建表格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. ;  

#browserPath = '/opt/phantomjs-2.1.1-linux-x86_64/bin/phantomjs'
#browserPath = '/usr/bin/phantomjs'
# 基本参数的一些准备工作
parser = 'html5lib'
domain = "weibo.com"
url_home = "http://" domain
download_bf = deque()                # 双向队列,用于保证多线程爬取是安全的
cur_queue = deque()
min_mblogs_allowed = 10              # 爬取的阈值设置
max_follow_fans_ratio_allowed = 3

澳门新萄京官方网站 6

# 这里有两个爬虫,一个爬取微博数据,一个爬取用户数据
weibo_澳门新萄京官方网站极客学院,爬到第10个信息以后不能再继续。driver = webdriver.Firefox()  # 微博爬虫
weibo_driver.set_window_size(1920, 1200)  # optional

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  

 

# url入队列,当然,入队列前要先做查重    
def enqueueUrl(url):
    try:
        md5v = hashlib.md5(url).hexdigest()
        if md5v not in download_bf: # 去重
            print(url ' is added to queue')
            cur_queue.append(url)
            download_bf.append(md5v)
        # else:
            # print 'Skip %s' % (url)
    except ValueError:
        pass

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 ( )'  

 

数据爬取效果展示:

澳门新萄京官方网站 7

# 队列左端弹出一个值
def dequeuUrl():
    return cur_queue.popleft()

四、总结:

1、学习了解scrapy框架写代码熟悉数据流的流程收获还是很多的。

2、感觉不是太复杂的网站应该都是可以抓的。形成了自己的一套系统知识体系,具体情况具体分析吧。

3、验证码这块简单的还能识别,复杂的可能得稍微用点深度学习了,识别率很一般,暂时还是人工输入吧。

4、爬虫只是很入门的技术,后续需要学的东西还好多。

额,看到这里也是不容易,说了这么多,关键还是直接打包工程源码:点击打开链接

 

 

转载:

# 到下一页取抓取        
def go_next_page(cur_driver):
    try:
        next_page = cur_driver.find_element_by_xpath('//a[contains(@class, "page next")]').get_attribute('href')
        print('next page is ' next_page)
        cur_driver.get(next_page)
        time.sleep(3)
        return True
    except Exception:
        print('next page is not found')
        return False

# 通过xpath尝试获取元素,最多尝试6次    
def get_element_by_xpath(cur_driver, path):
    tried = 0
    while tried < 6:
        html = cur_driver.page_source
        tr = etree.HTML(html)
        elements = tr.xpath(path)
        if len(elements) == 0:
            time.sleep(1)
            continue
        return elements

# 滚屏,保证能抓到数据            
def scroll_to_bottom():
    # 最多尝试 50 次滚屏
    print('scroll down')
    for i in range(0,50):
        # print 'scrolling for the %d time' % (i)
        weibo_driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
        html = weibo_driver.page_source
        tr = etree.HTML(html)
        next_page_url = tr.xpath('//a[contains(@class,"page next")]')
        if len(next_page_url) > 0:
            return next_page_url[0].get('href')
        if len(re.findall('点击重新载入', html)) > 0:
            print('scrolling failed, reload it')
            weibo_driver.find_element_by_link_text('点击重新载入').click()
        time.sleep(1)

# 提取微博数据
def extract_feed(feeds):
    for i in range(0,20):
    # 只有在抓取微博数据时需要滚屏
        scroll_to_bottom()
        for element in weibo_driver.find_elements_by_class_name('WB_detail'):
            tried = 0
            while tried < 3:
                try:
                    feed = {}
                    feed['time'] = element.find_element_by_xpath('.//div[@class="WB_from S_txt2"]').text
                    feed['content'] = element.find_element_by_class_name('WB_text').text
                    feed['image_names'] = []
                    for image in element.find_elements_by_xpath('.//li[contains(@class,"WB_pic")]/img'):
                        feed['image_names'].append(re.findall('/([^/] )$', image.get_attribute('src')))
                    feeds.append(feed)
                    print('--------------------')
                    print(feed['time'])
                    print(feed['content'])
                    break
                except Exception:
                    tried = 1
                    time.sleep(1)
        # 微博信息的下一页
        if go_next_page(weibo_driver) is False:
            return feeds

def getFollows(pageInfo):
    pattern3 = re.compile('class="S_txt1" title="(.*?)".*?usercard')
    follows = re.findall(pattern3, pageInfo)
    print(follows)
    for i in follows:
        print(i)
        #follower = {"name":i,"type":"follower"}
        #rs = followers.insert_one(follower)
        #print('one insert:{0}'.format(rs.inserted_id))
    
    ##urlsToScrawl = []
    ##urlsScrawled = []
    patterUrls = re.compile('<a bpfilter="page" class="page S_txt1"[sS]*?href="([sS]*?pids=Pl_Official_RelationMyfollow__92&cfs=&Pl_Official_RelationMyfollow__92_page=[sS]*?)"')
    follows = re.findall(patterUrls, pageInfo)
    for i in follows:
        print(")
        ##if i not in urlsScrawled and i not in urlsToScrawl:
        ##urlsToScrapy.append(")    

def login(current_driver,username, password):
    #driver = webdriver.PhantomJS(executable_path=browserPath)  #浏览器的地址
    #driver = webdriver.PhantomJS(desired_capabilities=dcap)
    #driver = webdriver.Firefox()
    #driver.set_window_size(1920, 1200)
    
    current_driver.get(url_home)  #访问目标网页地址
    #bsObj = BeautifulSoup(user_driver.page_source, parser)  #解析目标网页的 Html 源码
    time.sleep(10)
    #user_driver.save_screenshot("weiboLogin0.png")

    # 登录
    current_driver.find_element_by_id('loginname').send_keys(username)
    #user_driver.find_element_by_id('password').send_keys(password)
    #user_driver.find_element_by_xpath('//div[contains(@class,"input_wrap ")][0]/input').send_keys(password)
    current_driver.find_element_by_xpath('/html/body/div[1]/div[1]/div/div[2]/div[1]/div[2]/div/div[2]/div[1]/div[2]/div[1]/div/div/div/div[3]/div[2]/div/input').send_keys(password)
    # 执行 click()
    current_driver.find_element_by_xpath('//div[contains(@class,"login_btn")][1]/a').click()
    time.sleep(8)
    current_driver.save_screenshot("weiboLogin.png")

    ##verifyCode = input("Please input verify code:")            
    ##user_driver.find_element_by_xpath('/html/body/div[1]/div[1]/div/div[2]/div[1]/div[2]/div/div[2]/div[1]/div[2]/div[1]/div/div/div/div[3]/div[3]/div/input').send_keys(verifyCode)
    ##user_driver.find_element_by_xpath('//div[contains(@class,"login_btn")][1]/a').click()
    ##time.sleep(8)
    ##user_driver.save_screenshot("weiboLogin2.png")     

def main(username, password):
    # 登录
    #login(user_driver,username, password)
    login(weibo_driver,username, password)
    
    # 等会操作
    time.sleep(30)
    #user_driver.save_screenshot("weibo.png")
          
    ## 从大V的入口进去爬取,真正的URL入口
    user_link = ""
    print('downloading ' user_link)
    weibo_driver.get(user_link)
    time.sleep(5)
    
    # 提取用户姓名
    account_name = get_element_by_xpath(weibo_driver, '//h1')[0].text
    photo = get_element_by_xpath(weibo_driver, '//p[@class="photo_wrap"]/img')[0].get('src')
    account_photo = re.findall('/([^/] )$', photo)
    # 提取他的关注主页
    follows_link = get_element_by_xpath(weibo_driver, '//a[@class="t_link S_txt1"]')[0].get('href')
    print('account: ' account_name)
    print('account_photo: ' account_photo[0])
    print('follows link is ' follows_link)

    #user_driver.get("http" follows_link)
    feeds = []
    #users = []
     # 起一个线程取获取微博数据
    t_feeds = threading.Thread(target=extract_feed, name=None, args=(feeds,))
    t_feeds.start()
    t_feeds.join()     

if __name__ == '__main__':
    main("你的用户","你的密码")
    #login(user_driver,"570876459@qq.com", "xiaowuwu!!!")
    #login(weibo_driver,username, pass

本文由澳门新萄京官方网站发布于www.8455.com,转载请注明出处:澳门新萄京官方网站极客学院,爬到第10个信息以

关键词: