目录
- 简述网页爬虫的大致工作原理
- 读取网页源代码
- 读取网页中指定内容
- 保存读取到的内容——链接并写入数据库
- 进阶配置——反·反爬虫
- 反爬虫的大致原理
- 设置网页头(header)信息
- 设置暂停
- 设置ip代理
- 设置cookie
- 设置post
- 爬虫完整代码
实在不想写期中的BP作业……索性先趁着刚写完的热乎劲,给这篇攻略起个头。这篇攻略主要是针对文本信息的抓取,图片会稍微麻烦一点,假如需要的话,可能需要更多的HTML和CSS基础,并且要了解Python的保存语法。
本攻略需要一定的编程基础,和基本的HTML和CSS基础,虽然之后会有所讲解,但……怕省略了一些比较基础的说明,客官看不懂……
简单掌握一门编程语言,并且有基本HTML和CSS基础的客官可以跳过第一部分
简述网页爬虫的大致工作原理
首先,客官要明白网页的本质是什么样子的,你所看到的网页一般是这样的 ↓ ↓ ↓
但网站服务器发给浏览器的东西是这样的 ↓ ↓ ↓
我们需要抓取的内容都在后面这张图的文本里,例如超链接里面的地址就在标签a里的href属性里,例子如下。
<a title="频道首页" href="http://blog.csdn.net?ref=toolbar_logo" class="img blog-icon"></a>
其他的文本和图片信息也大致类似,无非是标签改成了<span>或<img>
或是其他,具体的就不在这里赘述了,如果不懂,可以去W3Cschool,或是菜鸟教程查看相关说明,或者直接去网易云课堂之类的地方跟着视频学一学html和css。
抓取流程大致为如下 ↓ ↓ ↓
今天先到这里,明天接着更
爬虫完整代码
代码还不精简,之后会删去一些不必要的内容
import requests # 导入requests 模块
import re
from urllib import request
from bs4 import BeautifulSoup # 导入BeautifulSoup 模块
import pymysql
import pymysql.cursors
import random
import time
import os # 导入os模块
class BeautifulPicture():
def __init__(self): # 类的初始化操作
self.web_url = 'http://su.58.com/job/pve_5363_244_pve_5358_0/' # 要访问的网页地址
def get_pic(self, p):
global count
web_url = 'http://su.58.com/tech/pn%d/' % (p)
config = {
'host': '127.0.0.1',
'port': 3306,
'user': '管理员名',
'password': '密码',
'db': '数据库名',
'charset': 'utf8'
}
print('开始网页get请求')
r = self.request(web_url)
print('开始获取所有a标签')
all_a = BeautifulSoup(r.text, 'lxml').find_all('dl', __addition='0') # 获取网页中的class为cV68d的所有a标签
i = 0
for a in all_a: # 循环每个标签,获取标签中图片的url并且进行网络请求,最后保存图片
img_str = a # a标签中完整的style字符串
matchObj = re.search(r'class="t".*?<', str(img_str))
if matchObj:
matchObj2 = re.search(r'f=".*?"', matchObj.group())
# print(' 开始网页get请求')
# print(matchObj2.group()[3:-1])
r2 = self.request(matchObj2.group()[3:-1])
matchObj_name = re.search(r'pos_name">.*?<', r2.text)
if matchObj_name:
a = (matchObj_name.group()[11:-1])
else:
a = "空"
print(" 空")
matchObj_title = re.search(r'pos_title">.*?<', r2.text)
if matchObj_title:
b = (matchObj_title.group()[12:-1])
else:
print(" 未读取到种类")
break
matchObj_salary = re.search(r'pos_salary">.*?<', r2.text)
if matchObj_salary:
c = (matchObj_salary.group()[12:-1])
else:
c = "面议"
matchObj_des = re.search(r'class="posDes".*?</', r2.text)
#print(matchObj_des.group())
d = (matchObj_des.group()[32:-2])
connection = pymysql.connect(**config)
try:
with connection.cursor() as cursor:
# 执行sql语句,插入记录
sql = 'INSERT INTO irm VALUES (%s, %s, %s, %s,"58")'
cursor.execute(sql, (a, b, c, d))
# 没有设置默认自动提交,需要主动提交,以保存所执行的语句
connection.commit()
finally:
connection.close();
i += 1
count += 1
print(" 本轮第%d条记录,共%d条记录" % (i,count))
if i % 20 == 0:
print("======暂停5秒======")
time.sleep(5)
def request(self, url): # 返回网页的response
user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
headers = {'User-Agent': user_agent,
"Referer": "http://su.58.com/tech"}
r = requests.get(url, headers=headers, timeout=10)
return r
def proxy_test(self, url):
try:
requests.get("http://www.baidu.cou", proxies={"http": url}, timeout=3)
except:
i = 0
else:
i = 1
return i
def Get_proxy_ip(self):
headers = {
'Host': 'www.xicidaili.com',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
'Accept': r'application/json, text/javascript, */*; q=0.01',
'Referer': r'http://www.xicidaili.com/',
}
req = request.Request(r'http://www.xicidaili.com/nn/', headers=headers)
response = request.urlopen(req)
html = response.read().decode('utf-8')
proxy_list = []
ip_list = re.findall(r'\d+\.\d+\.\d+\.\d+', html)
port_list = re.findall(r'<td>\d+</td>', html)
for i in range(len(ip_list)):
ip = ip_list[i]
port = re.sub(r'<td>|</td>', '', port_list[i])
proxy = '%s:%s' % (ip, port)
proxy_list.append(proxy)
return proxy_list
beauty = BeautifulPicture() # 创建类的实例
count = 0
for i in range(500,600):
print("======第%d页======"%(i))
time.sleep(2)
beauty.get_pic(i) # 执行类中的方法