刚学会了建 scrapy 框架,当然就忍不住想去练练手了,就挑个 51 job 去了解一下职位需求情况。
前面我们已经说了如何去创建一个 scrapy 框架,以及改一下 setting 配置文件,这里我们还要先再改一下 setting 文件:
改这里是因为现在很多网站都设置了反爬虫的保护机制,如果我们不加自己设的 user-agent ,就很容易被 “ban” ,从而爬取不到我们所要的数据,当然这只是防反爬虫的一种机制,大多数情况下都是可以的。下面是加的两行代码:
'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None, # 这一行是取消框架自带的useragent
'positionspiders.rotateuseragent.RotateUserAgentMiddleware': 400 #使用自己新置的 useragent 代理 ,第一个表示我们的工程名称,第二个是我们要新建的配置 user-agent 池的文件
那么下面先说下配置 useragent 池的文件 rotateuseragent (文件名字自己起):
import random
# 导入useragent用户代理模块中的UserAgentMiddleware类
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
# RotateUserAgentMiddleware类,继承 UserAgentMiddleware 父类
# 作用:创建动态代理列表,随机选取列表中的用户代理头部信息,伪装请求。
# 绑定爬虫程序的每一次请求,一并发送到访问网址。
# 发爬虫技术:由于很多网站设置反爬虫技术,禁止爬虫程序直接访问网页,
# 因此需要创建动态代理,将爬虫程序模拟伪装成浏览器进行网页访问。
class RotateUserAgentMiddleware(UserAgentMiddleware):
# the default user_agent_list composes chrome,I E,firefox,Mozilla,opera,netscape
# for more user agent strings,you can find it in http://www.useragentstring/pages/useragentstring.php
# 编写头部请求代理列表
user_agent_list = [ \
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1" \
"Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", \
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", \
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", \
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", \
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", \
"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", \
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", \
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", \
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", \
"Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3", \
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", \
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]
def __init__(self, user_agent=''):
self.user_agent = user_agent
def process_request(self, request, spider):
#这句话用于随机轮换user-agent
ua = random.choice(self.user_agent_list)
if ua:
# 输出自动轮换的user-agent
print("本次访问伪造的请求头是:", ua)
request.headers.setdefault('User-Agent', ua)
pass
pass
pass
现在我们设置了动态代理,接着就可以去写我们的爬虫代码了。先获取我们的目标网址,这里爬的是 python 的一些职位信息:
start_urls = ['https://search.51job/list/000000,000000,0000,00,9,99,python,2,1.html?lang=c&stype=&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&providesalary=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=']
接下来我们要去目标网页中找到目标路径,因为我们需要用到 xpath 路径表达式去获取我们需要的节点,所以我们先要去查看目标网页源码,找到目标节点:
即 class='el' 的div 节点下,下面就用到我们的 xpath 路径表达式去获取目标,如果对 xpath 不熟悉的,可以看下另一篇博客 xpath 全解:
jobDivItems=response.xpath("//div[@class='el']")
我们这里获取的所有 div 下 class 属性值等于 el 的标签节点,是一个复数列表,下面我们需要对其中的一条标签,详细获取其内容,这里我们要用到 scrapy 框架下的 items 文件 ,该文件的用途见 Items 理解 。
接下来我们还需要继续去网页中定位我们的目标节点:
下面获取该节点,并将获取的目标字段,通过 Item 类进行实例化:
jobDivItems=response.xpath("//div[@class='el']") #这里获取的是当前页下所有的职位信息
for jobDivItem in jobDivItems:
pItem=PositionspidersItem() # 创建 Item 类的一个对象
pItem['joblanguage']=PositionspiderSpider.jobType #将字段通过 Item 对象实例化
#print(jobDivItem.extract())
#print(jobDivItem.extract("//p[@class='t1']/span/a/text()"))
jobTitle = jobDivItem.xpath("//p[@class='t1 ']/span/a/text()").extract()
# extract(): 这个方法返回的是一个数组list,里面包含了多个string,如果只有一个string,则返回['ABC']这样的形式。
if len(jobTitle)>0:
pItem['jobTitle']=jobTitle[0].strip()
pass
else:
continue
jobComp=jobDivItem.xpath("span[@class='t2']/a/text()").extract()
jobAddress=jobDivItem.xpath("span[@class='t3']/text()").extract()
jobSalary=jobDivItem.xpath("span[@class='t4']/text()").extract()
jobTime=jobDivItem.xpath("span[@class='t5']/text()").extract()
if len(jobComp)>0:
pItem['jobComp'] = jobComp[0].strip()
pass
else:
continue
if len(jobAddress)>0:
pItem['jobAddress'] = jobAddress[0].strip()
pass
else:
continue
if len(jobSalary)>0:
pItem['jobSalary'] = jobSalary[0].strip()
pass
else:
continue
if len(jobTime)>0:
pItem['jobTime'] = jobTime[0].strip()
else:
continue
print(jobTitle)
print(jobComp)
print(jobAddress)
print(jobSalary)
print(jobTime)
yield pItem
pass
至于这个输出,我们在管道文件中也有定义:
到这里,我们如果输出的话就没问题了,但这只是一页的数据,才几十个,有点太少了,那下面我们就去爬下一页的,注意这里,是爬取下一页的,而不是指定前几页,意思就是如果我们不停止程序,它会一直往后爬,直到最后一页(现在都1337页了,爬完不知道得多长时间,我是没试过)。那下面就是去找下一页的跳转,我们看到当前页面最下面,是关于页数的跳转:
我们考虑一下这里会不会就有我们想到的信息,审查一下元素:
审查后发现,这里的下一页中含有一个链接,而这个链接就是下一页的地址。到这里就好办了,我们只需要获取对应路径结点下的内容信息就行了,下面我们仍使用 xpath 来定位结点,并获取下页的内容:
#开始解析下一页代码 获得下一页的超链接地址
nextPageURL=response.xpath("//div[@class='p_in']/ul/li[@class='bk']/a/@href").extract()
print("*****************",nextPageURL)
if nextPageURL: #如果判断一个列表为TUre 它是以这个列表的长度作为判断条件
url=response.urljoin(nextPageURL[-1])
print('url',url)
yield scrapy.Request(url,self.parse,dont_filter=False) #这一行我也比较迷
pass
else:
print("退出")
return
pass
这里面关键的那行代码我就有点迷,当时也没记住,爬虫还没深入学,也不清楚具体的使用,如果想了解的读者,可以自行去找一下,我因为时间问题,没空再深入学了。
到这里,简单 scrapy 爬取 51 就完成了, 后面是将爬取的内容保存入库,方面我们去看职位信息,见下一篇博客:scrapy 爬取51(二),顺便把这个小项目打包放网盘里分享一下。
更多推荐
初识爬虫 - scrapy 爬取 51 (一)
发布评论