最近要有一个任务,要爬取https://xueqiu.com/#/cn 网页上的文章,作为后续自然语言处理的源数据。

爬取目标:下图中红色方框部分的文章内容。(需要点击每篇文章的链接才能获得文章内容)

注:该文章仅介绍爬虫爬取新闻这一部分,爬虫语言为Python。

乍一看,爬虫的实现思路很简单:

(1)从原始页面https://xueqiu.com/#/cn上爬取各篇文章的URL

(2)通过第一步所获得的各篇文章的URL,抓取文章内容。

但是发现简单使用urllib2.urlopen()并不能获得红框部分的数据,原因是该部分数据是通过JS动态加载的。

最终发现可以采用Selenium框架来抓取动态数据。Selenium原本是Web测试工具,在Python爬虫中,可以使用它来模拟真实浏览器对URL进行访问,Selenium支持的浏览器包括Firefox、Chrome、Opera、Edge、IE 等。在此我使用的是Firefox浏览器。

Python爬虫脚本如下,可以参考注释来理解代码:

# coding=utf-8

import time

import Queue

import pymongo

import urllib2

import threading

from bs4 import BeautifulSoup

from BeautifulSoup import *

from selenium import webdriver

from selenium.webdriver.common.by import By

# 连接本地MongoDB数据库

client = pymongo.MongoClient()

# 数据库名为shsz_news

db = client.shsz_news

# collection名为news

collection = db.news

# 文章存储数据结构为:标题 作者 文章发布时间 阅读量 文章内容

# title author timestamp read content

class Article:

title = ""

url = ""

author = ""

timestamp = ""

read = 0

content = ""

def __init__(self, title, url, author, timestamp, read, content):

self.title = title

self.url = url

self.author = author

self.timestamp = timestamp

self.read = read

self.content = content

# 参数为:点击多少次"加载更多"

# 返回值为文章的url列表,数据总条数为:50 + 15 * num

def get_article_url(num):

browser = webdriver.Firefox()

browser.maximize_window()

browser.get('http://xueqiu.com/#/cn')

time.sleep(1)

# 将屏幕上滑4次,之后会出现“加载更多”按钮——此时有50篇文章

for i in range(1, 5):

browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')

time.sleep(1)

# 点击num次“加载更多”——每次点击会加载15篇新闻

for i in range(num):

# 找到加载更多按钮,点击

browser.find_element(By.LINK_TEXT, "加载更多").click()

time.sleep(1)

soup = BeautifulSoup(browser.page_source)

# 解析html,获取文章列表

article_queue = parse_html(soup)

browser.close()

return article_queue

# 解析html,返回Article的队列

def parse_html(soup):

article_queue = Queue.Queue()

article_divs = soup.findAll('div', {'class': 'home__timeline__item'})

if article_divs is not None:

for article_div in article_divs:

# 获取文章url

url = dict(article_div.h3.a.attrs)['href']

article_url = 'https://xueqiu.com' + url

# 获取文章标题

article_title = article_div.h3.a.string

# 获取文章作者

article_author = article_div.find('a', {'class': 'user-name'}).string

# 获取文章发布时间

article_timestamp = article_div.find('span', {'class': 'timestamp'}).string

# 获取文章阅读量

article_read = article_div.find('div', {'class': 'read'}).string

# 构造article对象,添加到article_queue队列中

article = Article(url=article_url, title=article_title, author=article_author,

timestamp=article_timestamp, read=article_read, content='')

article_queue.put(article)

return article_queue

# 获取文章内容的线程

class GetContentThread(threading.Thread):

def __init__(self, article_queue):

threading.Thread.__init__(self)

self.url_queue = article_queue

def run(self):

count = 0;

while 1:

try:

count += 1

# 打印每个线程的处理进度...

if count % 100 == 0:

print count

article = self.url_queue.get()

# 获取文章url

article_url = article.url

request = urllib2.Request(article_url)

request.add_header('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6')

response = urllib2.urlopen(request, timeout=10)

chunk = response.read()

soup = BeautifulSoup(chunk)

# 将文章内容解析出来

content = soup.find('div', {'class': 'detail'})

# 需要使用str()函数,否则无法保存到mongoDB中

article.content = str(content)

try:

# 将article信息写入mongoDB数据库

collection.save(article.__dict__)

except Exception, e:

# 该方法提示q.join()是否停止阻塞

self.url_queue.task_done()

# 将该文章重新放入队列

self.url_queue.put(article)

print "Save into MongoDB error!Let's make a comeback "

# 该方法提示q.join()是否停止阻塞

self.url_queue.task_done()

except Exception, e:

# 该方法提示q.join()是否停止阻塞

self.url_queue.task_done()

print 'get content wrong! ', e, '\n'

# 出现异常,将异常信息写入文件

file1 = open('get_content_wrong.txt', 'a')

file1.write(str(article.title) + '\n')

file1.write(str(article.url) + '\n')

file1.write(str(e) + '\n')

file1.close()

if '404' in str(e):

print 'URL 404 Not Found:', article.url

# 如果错误信息中包含 'HTTP' or 'URL' or 'url' ,将该地址重新加入队列,以便稍后重新尝试访问

elif 'HTTP' or 'URL' or 'url' in str(e):

self.url_queue.put(article)

print "Let's make a comeback "

continue

def main():

# 获得所有的文章,并将它们放入队列中

article_queue = get_article_url(150)

# 创建10个线程,获取所有文章的具体内容,并写入mongoDB数据库

for i in range(10):

gct = GetContentThread(article_queue)

gct.setDaemon(True)

gct.start()

# 等待队列中的所有任务完成

article_queue.join()

main()

python爬虫爬取雪球网_Python爬虫:Selenium+ BeautifulSoup 爬取JS渲染的动态内容(雪球网新闻)...相关推荐

  1. Python爬虫:Selenium+ BeautifulSoup 爬取JS渲染的动态内容(雪球网新闻)

    最近要有一个任务,要爬取https://xueqiu.com/#/cn 网页上的文章,作为后续自然语言处理的源数据. 爬取目标:下图中红色方框部分的文章内容.(需要点击每篇文章的链接才能获得文章内容) ...

  2. python 淘宝搜索_Python使用Selenium+BeautifulSoup爬取淘宝搜索页

    使用Selenium驱动chrome页面,获得淘宝信息并用BeautifulSoup分析得到结果. 使用Selenium时注意页面的加载判断,以及加载超时的异常处理. import json impo ...

  3. python爬虫爬取b站_python爬虫11 | 这次,将带你使用python爬取b站上的NBA形象大使蔡徐坤和他的球友们-Go语言中文社区...

    在上一篇中 小帅b给大家透露了我们这篇要说的牛逼利器 selenium + phantomjs 如果你看了 那么你应该知道 selenium 是什么了 它能做到自动操作 比如我们上次说的自动百度苍老师 ...

  4. python爬取小说基本信息_Python爬虫零基础实例---爬取小说吧小说内容到本地

    Python爬虫实例--爬取百度贴吧小说 写在前面本篇文章是我在简书上写的第一篇技术文章,作为一个理科生,能把仅剩的一点文笔拿出来献丑已是不易,希望大家能在指教我的同时给予我一点点鼓励,谢谢. 一.介 ...

  5. python爬取网页停止_Python爬虫之爬取静态网页

    所谓网络爬虫,通俗的讲,就是通过向我们需要的URL发出http请求,获取该URL对应的http报文主体内容,之后提取该报文主体中我们所需要的信息.所以,想要学习python爬虫,需要具备一些http的 ...

  6. python爬取bilibili弹幕_Python爬虫爬取Bilibili弹幕过程解析

    先来思考一个问题,B站一个视频的弹幕最多会有多少? 比较多的会有2000条吧,这么多数据,B站肯定是不会直接把弹幕和这个视频绑在一起的. 也就是说,有一个视频地址为https://www.bilibi ...

  7. python爬取cctalk视频_python爬虫urllib使用和进阶 | Python爬虫实战二

    python爬虫urllib使用和进阶 上节课已经介绍了爬虫的基本概念和基础内容,接下来就要开始内容的爬取了. 其实爬虫就是浏览器,只不过它是一个特殊的浏览器.爬取网页就是通过HTTP协议访问相应的网 ...

  8. python爬取数据步骤_Python爬虫爬取数据的步骤

    爬虫: 网络爬虫是捜索引擎抓取系统(Baidu.Google等)的重要组成部分.主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份. 步骤: 第一步:获取网页链接 1.观察需要爬取的多 ...

  9. python爬取空气质量指标_python爬虫之静态网页——全国空气质量指数(AQI)爬取

    首先爬取地址:http://www.air-level.com/ 利用的python库,最近最流行的requests,BeautifulSoup. requests:用于下载html Beautifu ...

  10. python爬取头条图集_Python爬虫基础练习(六) 今日头条街头篮球图片爬取

    今天我们要爬取的仍然是图片,不过与上一篇有所不一样的是,今天爬取的是今日头条上的图集,接着往下看吧~ 运行平台:Windows Python版本:Python3.6 IDE: Sublime Text ...

最新文章

  1. Android设备adb授权的原理【转】
  2. 开源监控系统 Prometheus 入门
  3. asp.net type=file前后台合作 在上传图片到服务器
  4. java-数据结构-续
  5. 【教女朋友学网络系列4】之今天教她一些简单的交换机实验
  6. 如何识别是三层交换机还是二层交换机
  7. Ayoa:让思维导图更简单,在线使用 无需安装客户端
  8. 【原】Web Polygraph 安装
  9. scala连接mongodb_MongoDB 的用户配置与基于Scala的使用
  10. 《Java语言程序设计》(基础篇原书第10版)第十三章复习题答案
  11. android手机录屏工具,安卓手机上有什么好用的屏幕录屏软件可以推荐?
  12. 记录淘宝里的点点滴滴
  13. 编程实现英语句子按单词倒叙-C语言
  14. linux木马查杀工具,【Kali】linux木马查杀
  15. Springboot实现定时任务调度
  16. (附源码)SSM学科竞赛赛场安排系统JAVA计算机毕业设计项目
  17. 腾讯云域名的报价表收费标准和活动报价
  18. python 操作微信_利用 Python 实现微信半自动化操作
  19. 19.通证的分类(各种分类一览表)
  20. 盘点IT行业“中国式合伙人”的离合春秋

热门文章

  1. 5G牌照发放 ,手机产业将迎来第二春
  2. 解决Oracle使用in语句不能超过1000问题
  3. PHP(euc) + Smarty(euc) で、UTF-8やSJIS出力する方法(解決策とまとめ)
  4. 贴心 | GXF Fix 修复 / 优化基因结构注释信息文件 - GTF/GFF3
  5. 蓝桥杯之桥本分数式(全排列函数应用)
  6. oracle数据库一个汉字占几个字节
  7. 不知道rar压缩包密码可以解密么,rar压缩包有密码怎么解开?
  8. 阿里云服务器配置DNS域名解析
  9. 51单片机~蜂鸣器,数码管的使用
  10. 什么是 Docker ?