【python3两小时快速入门】入门笔记03:简单爬虫+多线程爬虫
作用,之间将目标网页保存金本地
1、爬虫代码修改自网络,目前运行平稳,博主需要的是精准爬取,数据量并不大,暂未加多线程。
2、分割策略是通过查询条件进行分类,循环启动多条线程。
1、单线程简单爬虫(第二次整理)
import urllib.parse
import urllib.request
import os
import datetime
import json
#获取页面数据,返回整张网页
def getHtml(url,values):
user_agent='Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36'
headers = {'User-Agent':user_agent}
data = urllib.parse.urlencode(values)
response_result = urllib.request.urlopen(url+'?'+data).read()
html = response_result.decode('utf-8')
return html
#组装请求参数
def requestCnblogs(index):
print('请求数据')
url = 'http://xxx解析链接xxx.com/'
value= {
'param1': '',
'param2': '',
'param3': '308',
'page': index
}
result = getHtml(url,value)
return result
#print(requestCnblogs(1))
#通过IO流写出文件
def writeToTxt(html,file_path):
print(file_path)
try:
fp = open(file_path,"w+",encoding='utf-8')
fp.write(html)
fp.close()
except IOError:
print("fail to open file")
#创建文件夹
def createFile():
# date = datetime.datetime.now().strftime('%Y-%m-%d')
path = r'P:\Users' + '/foldername'
if os.path.exists(path):
return path
else:
os.mkdir(path)
return path
#保存页面
def saveBlogs():
i=1;
while 1==1:
try:
print('request for '+str(i)+'...')
blogs = requestCnblogs(i)
#保存到文件
path = createFile()
writeToTxt(blogs,path+'/filenames'+ str(i) +'.txt')
print('第'+ str(i) +'页已经完成')
i = i + 1;
except IOError:
print("sleep 10min and retry")
return 'success'
#开始搞事情
result = saveBlogs()
print(result)
并发爬虫:https://www.cnblogs.com/huohuohuo1/p/9064759.html
2、多线程爬虫(第二次整理)
这里是利用安全的队列保证线程安全,首先要将地址放入队列(摘抄自网络)
# coding=utf-8
import threading, queue, time, urllib
from urllib import request
baseUrl = 'http://www.pythontab.com/html/pythonjichu/'
urlQueue = queue.Queue()
for i in range(2, 10):
url = baseUrl + str(i) + '.html'
urlQueue.put(url)
#print(url)
def fetchUrl(urlQueue):
while True:
try:
#不阻塞的读取队列数据
url = urlQueue.get_nowait()
i = urlQueue.qsize()
except Exception as e:
break
print ('Current Thread Name %s, Url: %s ' % (threading.currentThread().name, url))
try:
response = urllib.request.urlopen(url)
responseCode = response.getcode()
except Exception as e:
continue
if responseCode == 200:
#抓取内容的数据处理可以放到这里
#为了突出效果, 设置延时
html = response.read().decode('utf-8')
time.sleep(1)
print(html)
if __name__ == '__main__':
startTime = time.time()
threads = []
# 可以调节线程数, 进而控制抓取速度
threadNum = 4
for i in range(0, threadNum):
t = threading.Thread(target=fetchUrl, args=(urlQueue,))
threads.append(t)
for t in threads:
t.start()
for t in threads:
#多线程多join的情况下,依次执行各线程的join方法, 这样可以确保主线程最后退出, 且各个线程间没有阻塞
t.join()
endTime = time.time()
print ('Done, Time cost: %s ' % (endTime - startTime))
3、自己改进了下(未整理,但正在使用)
# coding=utf-8
import threading, queue, time, urllib
import urllib.parse
import urllib.request
import os
import datetime
import json
from urllib import request
baseUrl = 'http://www.xxxxxxxxx.cn/xxx/402/'
urlQueue = queue.Queue()
def writeToTxt(html, file_path):
print(file_path)
try:
# 这里直接write item 即可,不要自己给序列化在写入,会导致json格式不正确的问题
fp = open(file_path, "w+", encoding='utf-8')
fp.write(html)
fp.close()
except IOError:
print("fail to open file")
#创建文件夹
def createFiles():
# date = datetime.datetime.now().strftime('%Y-%m-%d')
path = r'P:\Users3' + '/402'
if os.path.exists(path):
return path
else:
os.mkdir(path)
return path
for i in range(1, 881):
url = baseUrl + str(i) + "/"
urlQueue.put(url)
#print(url)
def fetchUrl(urlQueue):
while True:
try:
#不阻塞的读取队列数据
url = urlQueue.get_nowait()
i = urlQueue.qsize()
except Exception as e:
break
print ('Current Thread Name %s, Url: %s ' % (threading.currentThread().name, url))
try:
response = urllib.request.urlopen(url)
responseCode = response.getcode()
except Exception as e:
continue
if responseCode == 200:
#抓取内容的数据处理可以放到这里
#为了突出效果, 设置延时
html = response.read().decode('utf-8')
path = createFiles()
writeToTxt(html, path + '/filename' + str(i) + '.txt')
if __name__ == '__main__':
startTime = time.time()
threads = []
# 可以调节线程数, 进而控制抓取速度
threadNum = 4
for i in range(0, threadNum):
t = threading.Thread(target=fetchUrl, args=(urlQueue,))
threads.append(t)
for t in threads:
t.start()
for t in threads:
#多线程多join的情况下,依次执行各线程的join方法, 这样可以确保主线程最后退出, 且各个线程间没有阻塞
t.join()
endTime = time.time()
print ('Done, Time cost: %s ' % (endTime - startTime))
def saveBlogs():
i = 51; # 873
while 1 == 1:
try:
print('request for ' + str(i) + '...')
blogs = requestCnblogs(i)
# 保存到文件
path = createFiles()
writeToTxt(blogs, path + '/nongyeyinhang' + str(i) + '.txt')
print('第' + str(i) + '页已经完成')
i = i + 1;
except IOError:
print("sleep 10min and retry")
return 'success'
个人记录,处理下载的文件写入数据库(java代码):
package com.zzt.spider;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* 读取爬取的数据
* @author ZX
*
*/
public class ReadSpiderData3 {
public static void main(String[] args) {
List<String> folderList = new ArrayList<>();
//文件目录
File fileDir = new File("P:\\Users3\\102");
if(!fileDir.exists()){
return;
}
String[] list = fileDir.list();
for(String str :list) {//列出所有文件名
readTxt("P:\\Users3\\102\\"+str);
//return;
}
Scanner sc = new Scanner(System.in);
}
public static void readTxt(String path) {
try {
File file = new File(path);
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
int isVaribales=-1;
int lineCount=-1;//取1-20行有效数据
while ((line = br.readLine()) != null) {
if(line.contains("<th>SWIFT CODE</th>")){
isVaribales=1;
}
if(isVaribales==1) {
lineCount++;
if(lineCount>=1&&lineCount<84) {
if(line==null||"".equals(line.trim())) {
continue;
}
System.out.println(line);
//insertBank(code, name, phone, addr, "170");
}
}
if(line.contains("<div class=\"page\">")){
isVaribales=-1;
}
}
if (br != null) {
br.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 插入一条数据
*/
public static void insertBank(String BANK_CODE,String BANK_NAME,String BANK_PHONE,String BANK_ADDR,String BANK_NO) {
Connection connerction= createConn();
String sql="insert into SP_BANK_DETILS_S2 (BANK_CODE,BANK_NAME,BANK_PHONE,BANK_ADDR,BANK_NO) values(?,?,?,?,?)";
try {
PreparedStatement pstmt = connerction.prepareStatement(sql);
pstmt.setString(1, BANK_CODE);
pstmt.setString(2, BANK_NAME);
pstmt.setString(3, BANK_PHONE);
pstmt.setString(4, BANK_ADDR);
pstmt.setString(5, BANK_NO);
pstmt.executeUpdate();
closeConn(null, pstmt, connerction);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取jdbc链接
* @return
*/
private static Connection createConn(){
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn =DriverManager.getConnection("jdbc:mysql://192.168.0.100:3306/payrecdb?characterEncoding=utf8","name","pwd");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭所有资源
* @param rs
* @param stmt
* @param conn
*/
private static void closeConn(ResultSet rs,PreparedStatement stmt,Connection conn){
try {
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(conn!=null)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
【python3两小时快速入门】入门笔记03:简单爬虫+多线程爬虫的更多相关文章
- 【python3两小时快速入门】入门笔记01:基础
又要我搞爬虫了,这次的源网站使用的ajax加载数据,我用java爬下来的页面内容部分全都是空,虽然java也有插件,但是使用起来感觉很麻烦,所以,python!老子来了. 1. 版本:pytho ...
- 【python3两小时快速入门】入门笔记02:类库导入
昨晚遇到了一个问题:pip下载了request类库,以及在pyCharm的setting中下载了request类库,项目左侧也能显示出requst文件夹,但是引入报错! 这里贴一下我的解决方案,在此记 ...
- smarty半小时快速上手入门教程
http://www.jb51.net/article/56754.htm http://www.yiibai.com/smarty/smarty_functions.html http://www. ...
- 【python3两小时根本不够】入门笔记04:线程+Lock安全同步
有了简单爬虫,但是效率实在是太慢,于是决定启用线程进行爬取数据 但是对于临界资源的定义不好把握,思路如下: 1.定义队列(Queue的数据结构,List也可,安全性待考究) demo:https:// ...
- 两小时快速构建微信小程序
小程序在2017年1月上线之初,被社会极力吹捧,刻意去将其制造为一个“风口”,透支其价值.但是在之后一个月里,石破天惊迅速归为沉寂.媒体又开始过度消费小程序,大谈其鸡肋之处. 个人认为小程序的一个分水 ...
- 爬虫制作入门学习笔记2:[转]python爬虫实例项目大全
WechatSogou [1]- 微信公众号爬虫.基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫,返回结果是列表,每一项均是公众号具体信息字典. DouBanSpider [2]- ...
- python3.5学习笔记--一个简单的图片爬虫
参考资料:http://v.qq.com/boke/page/q/g/t/q01713cvdgt.html 目的:爬取网站图片 实际上以上链接的视频中已经将整个过程说的非常明白了,稍微有点计算机基础的 ...
- Nginx快速入门菜鸟笔记
Nginx快速入门-菜鸟笔记 1.编译安装nginx 编译安装nginx 必须先安装pcre库. (1)uname -a 确定环境 Linux localhost.localdomain 2.6. ...
- Sass简单、快速上手_Sass快速入门学习笔记总结
Sass是世界上最成熟.稳定和强大的专业级css扩展语言 ,除了Sass是css的一种预处理器语言,类似的语言还有Less,Stylus等. 这篇文章关于Sass快速入门学习笔记. 资源网站大全 ht ...
随机推荐
- 改变TLabel字型和颜色(Styled特性高于自身特性,李维的博客)
最近收到几位使用者的来信都是和如何改变FireMonkey TLabel组件的字型和颜色, 这几位使用者都是直接改变TextSettings特性中的Font子特性但却无法改变字型和颜色, 因此来信询问 ...
- AI2XAML's Bug(sequel)
原文:AI2XAML's Bug(sequel) I wrote an article about AI2XAML's Bug the day before yesterday. This arti ...
- ADO.net Connection对象简介
Connection对象 学习的是刘皓的文章 ADO.NET入门教程(四) 品味Connection对象 这篇文章开始水平一般起来了,主要介绍了要优雅的使用这个对象 1 用try...catch.. ...
- 国家模式c++
状态模式(State Pattern)是设计模式的一种,属于行为模式. 定义(源于Design Pattern):当一个对象的内在状态改变时同意改变其行为,这个对象看起来像是改变了其类. 状态模式主要 ...
- WPF内实现与串口发送数据和接收数据
原文:WPF内实现与串口发送数据和接收数据 与串口发送数据和接收数据,在此作一个简单的Demo.此Demo可以实现按下硬件按钮,灯亮,发送灯状态数据过来.并且可以实现几个灯同时亮,发送灯的状态数据过来 ...
- POJ3723 Conscription 【并检查集合】
Conscription Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8071 Accepted: 2810 Desc ...
- 二维码彩色广告招牌的切割制作问题(C#.net下对彩色二维码圆角样式及改进)
原文:二维码彩色广告招牌的切割制作问题(C#.net下对彩色二维码圆角样式及改进) 我们知道,目前二维码还很少用于广告招牌的制作.但随着智能手机越来越普及,互联网等网络的应用也越来越广泛,作为连接物理 ...
- C#如何在VS2015 2017版本中编写WPF UI界面引入第三方SVG图形
原文:C#如何在VS2015 2017版本中编写WPF UI界面引入第三方SVG图形 在VS2015 2017版本中编写WPF UI界面引入第三方SVG图形 最近在写WPF界面的时候遇到一个情 ...
- canvas——粒子系统(1)
这个动画在很早之前就见过,当时就没迷住了.最近在学canavs动画,动手实现了一下.代码在这里.展示效果在这里. 这属于粒子系统的一种,粒子系统就是需要管理一堆粒子嘛,动画实现的关键在于,遍历这些粒子 ...
- Win10《芒果TV》商店版更新v3.1.3.0:优化应用速度,支持会员卡兑换
在微软秋季Win10/Surface新品发布会热潮之后,<芒果TV>UWP版迅速更新v3.1.3版,优化应用启动速度,支持会员卡券兑换,新增全网搜索.记忆播放.消息推送等功能. 芒果TV ...